本文介绍了JavaScript内存泄漏,循环内函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在遍历从ajax响应中获得的响应,该响应是一个包含1000个对象的数组,该响应用于创建具有1000行的html表:

I am looping over a response that I got from an ajax response, the response is an array containing 1000 objects , this response is used to created an html table with 1000 rows :

第一种情况:

    for (var i in msg.myObjects) {
    $('#mytablebody').append('<tr><td>' + msg.myObjects['item1'] + '</td><td>' +
msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>');
    }

结果=>内存泄漏我的RAM进入2Go,浏览器崩溃了

Result => memory leak my RAM went to 2Go and my browser crashed

第二种情况:

    for (var i in msg.myObjects) {
        document.getElementById('mytablebody').innerHTML = document.getElementById('mytablebody').innerHTML + '<tr><td>' +
msg.myObjects['item1'] + '</td><td>' +
    msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
    msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
    msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>';
        }

结果=>内存泄漏我的RAM达到800Mo,浏览器因第二次Ajax调用而崩溃

Result => memory leak my RAM went to 800Mo and my browser crashed with a second ajax call

第三种情况:

var stringResponse = '';
        for (var i in msg.myObjects) {
            stringResponse += '<tr><td>' + msg.myObjects['item1'] + '</td><td>' +
        msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
        msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
        msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>';
            }
document.getElementById('mytablebody').innerHTML = stringResponse

结果=>没有内存泄漏

好吧,直到这里我得出结论,首先,.append()会导致内存泄漏,其次,永远不要在循环内使用DOM元素.但是当我做第四个场景时,我得出的结论是,第一个结论是错误(并不完全正确),而第二个结论仍然是正确的.

Ok until here I concluded that, first of all, .append() causes memory leaks, and second of all , you should never play with DOM elements inside a loop. But when I did the 4th scenario I concluded that the first conclusion was wrong (not exactly correct) and the second one is still correct.

第四种情况:

    var stringResponse = '';
            for (var i in msg.myObjects) {
                stringResponse += '<tr><td>' + replaceNulls(msg.myObjects['item1']) + '</td><td>' +
            msg.myObjects['item2'] + '</td><td>' + msg.myObjects['item3'] + '</td><td>' +
            msg.myObjects['item4'] + '</td><td>' + msg.myObjects['item5'] + '</td><td>' +
            msg.myObjects['item6'] + '</td><td>' + msg.myObjects['item7'] + '</td> .... </tr>';
                }
    document.getElementById('mytablebody').innerHTML = stringResponse

function replaceNulls(input) {
  return input != null ? input : ''
}

结果=>内存泄漏我的RAM进入2Go,浏览器崩溃了

Result => memory leak my RAM went to 2Go and my browser crashed

我的问题是:

当我们调用发生在循环外部的函数时,可能会导致内存泄漏,为什么?

when we call functions that occurs outside a loop , it may causes a memory leak, why ?

如何避免这种情况(不删除函数或将其处理移入循环内部)?

How can I avoid this (without removing the function or moving its processing to inside the loop) ?

推荐答案

现代Web浏览器的1000个表条目应该不会引起任何问题.

1000 table entries for modern web browsers should not cause any issue.

在这里,我将10,000个项目添加到没有ram问题的表中.之所以如此之快,是因为我在一个独立的DOM元素中建立了列表,然后在完成后附加.

Here I'm adding 10,000 items into a table without ram problems.The reason why it's fast is because I build up the list inside a detached DOM element, then attach when done.

您的问题可能仅在于DOM绘制问题,浏览器必须重新绘制所有更新.

Your problem might be just down to DOM draw issue, the browser having to redraw on all your updates.

我注意到的另一件事,for (var i in msg.myObjects)取决于您的msg.myObjects所包含的内容,不是一件好事.如果可以使用现代JS ,. for (const i of msg.myObjects)更好.

Another thing I noticed, for (var i in msg.myObjects) depending on what your msg.myObjects contains this is not a good thing to use. If you can use modern JS,. for (const i of msg.myObjects) is better.

var table = document.querySelector("table");

var tbody = document.createElement("tbody");

function addLine (txt) {
  var tr = document.createElement("tr");
  var td = document.createElement("td");
  tr.appendChild(td);
  td.innerText = txt;
  tbody.appendChild(tr);
}

for (var l = 1; l <= 10000; l += 1) {
  addLine("This is Line " + l + ", and some extra text");
}

table.appendChild(tbody);
<table>
  <thead><tr><th>Test</th></tr></thead>

</table>

这篇关于JavaScript内存泄漏,循环内函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 18:36