部分垃圾收集的对象可能? (服务器端JS) [英] Partial garbage collection of objects possible? (server-side JS)

查看:93
本文介绍了部分垃圾收集的对象可能? (服务器端JS)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设一个服务器端JavaScript环境,它提供了如下的函数:

  var parseIsoDuration = / ... complex正则表达式... / 

函数dateDiff(date,isoDurationStr){
var duration = parseIsoDuration.exec(isoDurationStr);
返回timeLibrary.add(日期,持续时间);
}

该函数将从外部调用,数百个日期,但大多数相同的ISO时间。由于RexExp解析不是一个便宜的操作,因此可以实现应用程序级别的缓存:

  var parseIsoDuration = / ... complex正则表达式... / 
var durationCache = {}

函数dateDiff(date,isoDurationStr){
var duration;
if(durationCache [isoDurationStr] === undefined){
duration = parseIsoDuration.exec(isoDurationStr);
durationCache [isoDurationStr] =持续时间;
} else {
duration = durationCache [isoDurationStr];
}
return timeLibrary.add(date,duration);
}

问题:服务器可能会连续运行一年,并且缓存对象永远不会超出范围。如果函数被调用的时间长度不同,那么缓存将随着时间的推移而增长,并且永远不会减小它的大小。



有没有办法告诉V8它可能会根据需要清除缓存对象中的旧条目(例如,增长过大)?或者至少根据需要将其完全清楚? (解决方案可能取决于ES6 / 7的功能)

ES6 WeakMaps声音很有趣,但它们只接受对象作为键。在数组中包装一个字符串使其成为一个对象将不起作用,因为再次这样做会导致不同的对象。我需要像 Symbol(str)之类的东西,但是它会为两个相同的输入( Ref(str)=== Ref(str ))。



edit:其实有 Symbol.for(str) === Symbol.for(str),但它不被接受为WeakMap键。



我也不确定何时输入在WeakMap的情况下实际上会被垃圾收集 - 它可能会立即或多或少,因为在将对象添加到WeakMap后没有对该对象的引用。所以一个双重号码。

取消设置个别密钥在添加时需要额外的簿记,并且需要一些算法来确定合理的TTL。

是否有必要缓存RegExp结果?有一些内置的缓存吗?对于文字表达式,还是仅通过构造函数创建,或者两者兼而有之?

解析方法

你所说的听起来像Java的 SoftReference ,不,在v8中没有这样的东西。相反,您应该自己管理缓存或使用其中一个模块,例如 lru-cache


Assume a server-side JavaScript environment, that provides a function like so:

var parseIsoDuration = /... complex regex .../

function dateDiff(date, isoDurationStr){
    var duration = parseIsoDuration.exec(isoDurationStr);
    return timeLibrary.add(date, duration);
}

That function will be called from outside, on hundreds of dates, but mostly the same ISO duration. Because RexExp parsing is not a cheap operation, an application-level cache could be implemented:

var parseIsoDuration = /... complex regex .../
var durationCache = {}

function dateDiff(date, isoDurationStr){
    var duration;
    if (durationCache[isoDurationStr] === undefined){
        duration = parseIsoDuration.exec(isoDurationStr);
        durationCache[isoDurationStr] = duration;
    } else {
        duration = durationCache[isoDurationStr];
    }
    return timeLibrary.add(date, duration);
}

The problem: the server may run for a year straight, and the cache object never goes out of scope. If the function is called with a lot different ISO duration strings, the cache will grow over time and never reduce its size.

Is there a way to tell V8 that it may clear "old" entries from the cache object as needed (i.e. has grown too large)? Or at least make it clear it entirely as the need arises? (Solution may depend on ES6/7 features)

ES6 WeakMaps sound interesting, but they accept objects as keys only. Wrapping a string in an array to make it an object will not work, because doing that again will result in a different object. I would need something like Symbol(str), but that returns an identical reference for two identical inputs (Ref(str) === Ref(str)).

edit: There's actually Symbol.for("str") === Symbol.for("str"), but it's not accepted as WeakMap key.

I'm also not sure when entries would actually be garbage-collected in case of a WeakMap - it might be more or less immediately, because there would be no reference to the object right after it was added to the WeakMap. So a double no.

Unsetting individual keys would require additional book-keeping when they were added and some algorithm to determine a sensible TTL.

Is it necessary to cache the RegExp results even? Is there some built-in cache? For literal expressions or if created via constructor only, or both?

解决方案

What you are talking about sounds like Java's SoftReference and no, there is nothing like this in v8. Instead you should manage cache yourself or use one of the modules like lru-cache

这篇关于部分垃圾收集的对象可能? (服务器端JS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆