部分垃圾收集对象可能吗?(服务器端JS)

Partial garbage collection of objects possible? (server-side JS)

本文关键字:服务器端 JS 对象      更新时间:2023-09-26

假设服务器端JavaScript环境,提供如下函数:

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

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

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);
}

问题:服务器可能连续运行一年,缓存对象永远不会超出作用域。如果使用很多不同的ISO持续时间字符串调用该函数,则缓存将随着时间的推移而增长,并且永远不会减小其大小。

是否有一种方法可以告诉V8,它可以根据需要从缓存对象中清除"旧"条目(即已经增长得太大)?或者至少在需要的时候完全说清楚?(解决方案可能取决于ES6/7的特性)

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

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

我也不确定在WeakMap的情况下条目什么时候会被垃圾收集——它可能或多或少是立即收集的,因为在对象被添加到WeakMap之后就没有对它的引用了。所以两个no

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

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

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

之类的模块。