我读过一篇关于内存泄漏的文章,其中垃圾回收器逻辑总结为:
1. 垃圾回收器构建一个“根”列表。根通常是在代码中保留引用的全局变量。在JavaScript中,“window”对象就是一个可以充当根的全局变量的例子。窗口对象始终存在,因此垃圾回收器可以将其及其所有子项视为始终存在(即不是垃圾)。
2. 检查并标记所有根为活动状态(即不是垃圾)。也要递归地检查所有子元素。从根可以到达的所有内容都不被视为垃圾。
3. 所有未标记为活动状态的内存块现在都可以视为垃圾。垃圾收集器现在可以释放该内存并将其返回给操作系统。
此外,MDN指出DocumentFragment不是活动DOM树的一部分。
文档片段接口表示没有父级的最小化文档对象。它用作Document的轻量级版本,其存储了由节点组成的文档结构段,就像标准文档一样。主要区别在于,因为文档片段不是活动文档树结构的一部分,对片段进行更改不会影响文档、引起重排或产生任何性能影响。
逐步了解逻辑,但非常希望有人可以为我提供更多解释。使用以下示例并说明:
1. 在使用DOM引用后将其设为null被认为是一种良好的实践。
2. 是否需要将对DocumentFragment和包含它的元素的引用设为null。
1. 垃圾回收器构建一个“根”列表。根通常是在代码中保留引用的全局变量。在JavaScript中,“window”对象就是一个可以充当根的全局变量的例子。窗口对象始终存在,因此垃圾回收器可以将其及其所有子项视为始终存在(即不是垃圾)。
2. 检查并标记所有根为活动状态(即不是垃圾)。也要递归地检查所有子元素。从根可以到达的所有内容都不被视为垃圾。
3. 所有未标记为活动状态的内存块现在都可以视为垃圾。垃圾收集器现在可以释放该内存并将其返回给操作系统。
此外,MDN指出DocumentFragment不是活动DOM树的一部分。
文档片段接口表示没有父级的最小化文档对象。它用作Document的轻量级版本,其存储了由节点组成的文档结构段,就像标准文档一样。主要区别在于,因为文档片段不是活动文档树结构的一部分,对片段进行更改不会影响文档、引起重排或产生任何性能影响。
逐步了解逻辑,但非常希望有人可以为我提供更多解释。使用以下示例并说明:
1. 在使用DOM引用后将其设为null被认为是一种良好的实践。
2. 是否需要将对DocumentFragment和包含它的元素的引用设为null。
function usefulFunction() {
let existingNode = document.querySelector(`.existing`)
let createdNode = document.createElement(`ul`)
let fragment = document.createDocumentFragment();
let browsers = ['Firefox', 'Chrome', 'Opera',
'Safari', 'Internet Explorer'];
browsers.forEach(function(browser) {
var li = document.createElement('li');
li.textContent = browser;
fragment.appendChild(li);
});
existingNode.appendChild(createdNode)
createdNode.appendChild(fragment)
fragment = null
createdNode = null
existingNode = null
}
usefulFunction()
<div class="existing"></div>
更新片段
let existingNode
function helperFunction(object) {
let createdNode = document.createElement(`div`)
createdNode.innerHTML = `Hello, I am a beautiful div`
existingNode.appendChild(createdNode)
existingNode = null
}
function usefulFunction() {
existingNode = document.querySelector(`.existing`)
let fragment = document.createDocumentFragment();
let browsers = ['Firefox', 'Chrome', 'Opera',
'Safari', 'Internet Explorer'];
browsers.forEach(function(browser) {
var li = document.createElement('li');
li.textContent = browser;
fragment.appendChild(li);
});
existingNode.appendChild(fragment)
helperFunction()
}
usefulFunction()
<div class="existing"></div>