为什么反序列化目标数组的序列化副本会修复内存泄漏问题?

时间:2012-09-18 08:51:53

标签: javascript json algorithm node.js

我有两个用于重复数据删除和搜索数组的函数。这是微不足道的东西。我注意到在某些情况下对于具有超过大约100个元素的数组,当使用这些函数时会发生巨大的内存泄漏,并且我的node.js javascript应用程序将会死亡。

我的数组arr可能是“错误的”,这意味着反序列化它的序列化版本修复了mem泄漏?为什么反序列化目标数组的序列化副本会修复内存泄漏问题?

可能相关:

arr是通过几十个连接调用构建的。

搜索功能:

function findObjInArray(arr, obj, lookupKeyChain){
    var tmpObj = undefined;
    for(var i = 0; i < arr.length; i++){
        tmpObj = arr[i];
        for(var j = 0; j < lookupKeyChain.length; j++){
            tmpObj = tmpObj[lookupKeyChain[j]]
            if(!tmpObj){
                break;
            }else if(j==lookupKeyChain.length-1){
                if(tmpObj==obj){
                    return arr[i];
                }
            }
        }
    }
    return undefined;
}

重复数据删除功能:

function combineProducts(productList, idKey){
    var deDupedProducts = []
    for(var i = 0; i < productList.length; i++){
        var precedent = findObjInArray(deDupedProducts, productList[i][idKey], [idKey]);
        if(precedent){
            //just add tag data to precedent
            for(var j = 0; j < productList[i].tags.length; j++){
                precedent.tags.push(productList[i].tags[j]);
            }
        }else{
            deDupedProducts.push(productList[i]);
        }
    }
    return deDupedProducts;
}

arr中结构的一个例子:

    [
        {
            "price": "$9.99",
            "name": "Big Widgets",
            "tags": [
                {
                    "tagClass": "Category",
                    "tagName": "On Sale"
                }
            ]
        },
        {
            "price": "$5.00",
            "name": "Small Widgets",
            "tags": [
                {
                    "tagClass": "Category",
                    "tagName": "On Sale"
                },

            ]
        },
        ...
    ]

导致内存泄漏的调用:

combineProducts(
    arr,
    "name"
)

解决问题并给我正确结果的电话:

combineProducts(
    JSON.parse(JSON.stringify(arr)),
    "name"
)

1 个答案:

答案 0 :(得分:1)

不相关,但对于大型列表而言,基于对象的算法比不断扩展的线性搜索更有效(和简洁)。

function combineProducts(productList, idKey) {
    var lookup = {};

    productList.forEach(function(product) {
        var precedent = lookup[product[idKey];

        if (precedent) {
            precedent.tags = precedent.tags.concat(product.tags);
        }
        else {
            lookup[product[idKey]] = product;
        }
    });

    return Object.keys(lookup).map(function(idValue) {
        return lookup[idValue];
    });
}

唯一不同的是你的功能是不保留排序(尽管如果数据是由idKey排序开始的,单程算法会更好)。