gpt4 book ai didi

javascript - DOM 何时从内存中移除?

转载 作者:技术小花猫 更新时间:2023-10-29 12:55:48 25 4
gpt4 key购买 nike

我正在开发一个创建和删除大量 DOM 的应用程序。我注意到浏览器选项卡中的进程内存不断增加,尽管 javascript 堆内存保持不变。在测试应用程序中,我从父 div 创建和删除 div。

http://jsfiddle.net/PSxPz/2/

<button onclick="createStuff()">Create</button>
<button onclick="deleteStuff()">Delete</button>
<div id="parent"></div>

function createStuff() {
var parentDiv = document.getElementById('parent');
for (var i = 0; i < 50000; i++) {
var child = document.createElement('div');
child.id = i;
child.textContent = i;

parentDiv.appendChild(child);
child = null;
}

parentDiv = null;
}

function deleteStuff() {
var parentDiv = document.getElementById('parent');
for (var i = 0; i < 50000; i++) {
var child = document.getElementById(i);
parentDiv.removeChild(child);
child = null;
}

parentDiv = null;
}

我已经确认 javascript 堆没有通过 chrome 开发工具泄漏(我是新手,所以我可能错过了一些东西)。但是,该过程的内存继续增加。从我读过的所有内容来看,我怀疑删除的 dom 仍在 dom 堆中。

其他帖子还说浏览器最终会释放分配给已删除 dom 的内存。在上面的 jsfiddle 示例中,我多次点击创建和删除。我的 javascript 堆稳定在 4.9MB。我的进程内存高达 115MB。我已经等了 30 分钟了,它一点也没有下降。

问题

  1. 删除的 DOM 元素何时从浏览器进程内存中完全删除?
  2. 有没有办法强制执行 DOM 垃圾回收?
  3. 是否有工具可以更深入地了解哪些 dom 被标记为垃圾回收?我在 Chrome 或 IE 中找不到。

感谢您的帮助!

编辑

我已经使用了 chrome 开发工具,javascript 堆没有增长。有趣的是,堆快照之间唯一发生变化的是一个(数组)对象。据我了解,括号中的任何内容都由浏览器控制并且超出我的范围。每个后续的 create->delete 都会删除旧的(数组)对象并在删除过程中创建一个新对象。

在时间轴上我可以看到 javascript 堆是常量并且节点被清理了,但是即使在节点数下降之后,用 (shift + esc) 显示的内存也不会下降。

enter image description here enter image description here

似乎我正在尽我所能确保清理我的 javascript 堆,但 dom 清理超出我的范围并且独立于 javascript GC。这种说法正确吗?

被移除的doms是否属于新生代堆?有没有办法对此堆大小设置限制?我重复测试,直到达到 500MB,但仍然没有清理。我正在使用 Chrome 35.0.1916.114 顺便说一下。

最佳答案

我知道您问过有关 Chrome 的问题,但我将描述它在 Firefox 中的工作原理,希望您和其他读者可能会对它感兴趣。 Chrome 可能会以类似的方式工作,我不确定。

对于您的测试用例,Firefox 内存使用量不会持续增加。只有在您第一次创建/删除元素时,内存使用量才会永久增加。 在随后的创建/删除周期中,所有分配的内存随后都会被回收。

至少在 Firefox 中,您不能在不重新加载页面的情况下强制释放此内存。如果您真的需要临时分配这么多内存,您应该在 iframe 中执行此操作,完成后可以丢弃。

技术细节如下:


在 Firefox 中,有一个名为 about:memory 的工具可以检查内存使用情况。 .它按类别分解已用内存,并具有强制清理内存(GC/CC/最小化内存)的控件。

下面是 about:memory 的相关部分在您创建/删除 DOM 元素后以及 GC 启动后的样子:

├──34.34 MB (03.30%) -- window(http://fiddle.jshell.net/PSxPz/2/show/)
│ ├──26.54 MB (02.55%) -- layout
│ │ ├──13.95 MB (01.34%) -- (8 tiny)
│ │ │ ├───7.63 MB (00.73%) ── line-boxes
│ │ │ ├───4.00 MB (00.38%) ── pres-contexts
│ │ │ ├───2.26 MB (00.22%) ── pres-shell
│ │ │ ├───0.04 MB (00.00%) ── style-structs
│ │ │ ├───0.01 MB (00.00%) ── rule-nodes
│ │ │ ├───0.01 MB (00.00%) ── style-contexts
│ │ │ ├───0.00 MB (00.00%) ── style-sets
│ │ │ └───0.00 MB (00.00%) ── text-runs
│ │ └──12.59 MB (01.21%) -- frames
│ │ ├───7.25 MB (00.70%) ── nsBlockFrame
│ │ ├───5.34 MB (00.51%) ── nsTextFrame
│ │ └───0.00 MB (00.00%) ── sundries
│ └───7.80 MB (00.75%) -- (4 tiny)
│ ├──7.51 MB (00.72%) ++ dom
│ ├──0.29 MB (00.03%) ++ js-compartment(http://fiddle.jshell.net/PSxPz/2/show/)
│ ├──0.00 MB (00.00%) ── style-sheets
│ └──0.00 MB (00.00%) ── property-tables

(如果 DOM 节点已从文档中删除,但尚未被垃圾回收,它们将显示在 orphan-nodes 测量下。)

大部分额外内存(在创建 DOM 节点时请求)保留用于布局。

  • Firefox 和其他浏览器一样,创建一个单独的 rendering tree (called frame tree in Gecko) based on DOM and CSS .这是一个实现细节,网页完全无法访问。
  • Gecko 中的帧分配自 arenas .
  • 布局(所谓的 PresShell)领域在没有更多的帧可以容纳已分配的空间时从操作系统分配额外的内存(当您首次创建 50,000 个 DOM 元素时会发生这种情况),但不要将其释放回操作系统直到页面被卸载。

此行为 is基于显示现实生活中的网页在其生命周期中通常需要大约相同数量的布局对象的测量:一个典型的网页不会分配 10,000 个框架只是为了销毁它们并显示一个非常简单的页面,比如这里的测试用例。

这种内存管理行为在提高帧分配/解除分配速度方面得到返回,减少了 memory fragmentation ,并避免在销毁框架后访问框架时出现严重的安全错误。

关于javascript - DOM 何时从内存中移除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23926550/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com