1

我有一个记忆的 fn,其中 fn 由两个输入引用记忆:

let NewRefCursor = memoized(
    (deref, swap) => refToHash(deref) + refToHash(swap), // memoizer identity fn
    (deref, swap) => new RefCursor(deref, swap)); // the function we are memoizing

我需要的行为是NewRefCursor(a, b) === NewRefCursor(a, b). 当ab被垃圾回收时,游标也应该被垃圾回收。

refToHash是另一个使用ES6WeakMap的记忆函数,因此仍然允许看到的引用被 GC。

NewRefCursor记忆起来要棘手得多,因为它使用两个参数来确定缓存命中,因此与 不兼容WeakMap,因此将阻止看到的任何引用被 GC'ed。我对任何形式的诡计持开放态度,将私有字段附加到输入对象、概率数据结构。这个泄漏需要解决。到目前为止,我唯一的解决方案是添加一个参数来限制缓存大小,并在每个应用程序的基础上调整该参数。总的。

4

2 回答 2

3

If you create a two level weak-map (store weakmaps on weakmaps), whenever a obj on first level is gced, you lose the whole second level (when a is gced, you lose b). If b is gced, you will still have a weakmap for a, which will only be there while there is another pair (a, something). Not the best implementation, but I think it suffices:

function BiWeakMap() {
    this._map = new WeakMap();
}

BiWeakMap.prototype.set = function(key1, key2, value) {

    if (!this._map.has(key1)) {
        this._map.set(key1, new WeakMap());
    }

    this._map.get(key1).set(key2, value);

    return this;

};

BiWeakMap.prototype.has = function(key1, key2) {

    return this._map.has(key1) && this._map.get(key1).has(key2);

};

BiWeakMap.prototype.get = function(key1, key2) {

    return this._map.get(key1) && this._map.get(key1).get(key2);

};

This concept can be extended to a n-level solution. Does this solve your problem or am I missing something?

于 2015-12-29T13:52:02.297 回答
0

请参阅https://github.com/Dans-labs/dariah/blob/master/client/src/js/lib/utils.js中的memoize 它通过构建所有参数的 WeakMap 索引以通用方式解决问题对象。WeakMap 索引为对象分配唯一的整数,然后可以通过 stringify 将其与其他参数放在一起。

于 2017-06-08T19:58:35.900 回答