- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我正在开发一个创建和删除大量 DOM 的应用程序。我注意到浏览器选项卡中的进程内存不断增加,尽管 javascript 堆内存保持不变。在测试应用程序中,我从父 div 创建和删除 div。
<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 分钟了,它一点也没有下降。
问题
感谢您的帮助!
编辑
我已经使用了 chrome 开发工具,javascript 堆没有增长。有趣的是,堆快照之间唯一发生变化的是一个(数组)对象。据我了解,括号中的任何内容都由浏览器控制并且超出我的范围。每个后续的 create->delete 都会删除旧的(数组)对象并在删除过程中创建一个新对象。
在时间轴上我可以看到 javascript 堆是常量并且节点被清理了,但是即使在节点数下降之后,用 (shift + esc) 显示的内存也不会下降。
似乎我正在尽我所能确保清理我的 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 节点时请求)保留用于布局。
此行为 is基于显示现实生活中的网页在其生命周期中通常需要大约相同数量的布局对象的测量:一个典型的网页不会分配 10,000 个框架只是为了销毁它们并显示一个非常简单的页面,比如这里的测试用例。
这种内存管理行为在提高帧分配/解除分配速度方面得到返回,减少了 memory fragmentation ,并避免在销毁框架后访问框架时出现严重的安全错误。
关于javascript - DOM 何时从内存中移除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23926550/
我正在做一个项目,我的 android 在这个项目中作为一个网络服务器工作;输入带端口号的 IP 地址,打开 Web 界面,用户可以将文件上传到手机。我想在 Web 界面上显示一些图片,以便我们的界面
我是一名优秀的程序员,十分优秀!