0

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

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

可能相关:

arr 是通过对 concat 的几十次调用构建的。

搜索功能:

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"
)
4

1 回答 1

1

Unrelated, but an object-based algorithm is much more efficient (and concise) for large lists than your ever-expanding linear search.

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

Only difference to your function is that ordering is not preserved (though if the data was ordered by the idKey to start with, a single-pass algorithm would be even better).

于 2012-09-18T09:13:35.910 回答