javascript - 为什么反序列化我的目标数组的序列化副本可以修复内存泄漏问题?

标签 javascript json algorithm node.js

我有两个函数用于重复数据删除和搜索数组。这是微不足道的事情。我注意到在某些情况下,对于包含超过 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"
)

最佳答案

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

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 开始排序,则单遍算法会更好)。

关于javascript - 为什么反序列化我的目标数组的序列化副本可以修复内存泄漏问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12473495/

相关文章:

javascript - AngularJS:带有 HTML 和 Angular 表达式的指令, "compile"具有外部范围的内容

javascript - jQuery 弹出/叠加效果

javascript - NodeJS 和 EJS 的 JSON 字符串化问题

c# - 根据列值隐藏单个 JSON 值的任何简单方法?

javascript - collat​​z 序列的最大长度 - 优化

javascript - Jest – 模拟窗口或文档对象

javascript - 如何证明我的 JavaScript 文件在特定 JS 或 ECMA 版本的范围内?

android - 在 Android 的 API 8 中使用 JSON Reader

algorithm - 从最低共同祖先重建树的算法名称?

algorithm - 比较两个词的相似度