javascript - 为什么 chrome 任务管理器内存占用显着增加(170mb)仅在一个 div 的 innerHTML 中呈现 10mb 字符串?
问题描述
我做了一个小测试,在单击按钮时创建了一个 10mb 的字符串。然后在第二个按钮上单击我在 div 的 innerHTML 中呈现该字符串内容。
编码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<button id="btn-load">Load string</button>
<button id="btn-render">Render string</button>
<div id="place-to-render"></div>
<script type="module" src="main.js"></script>
</body>
</html>
JS main.js:
let data;
function createBigString() {
data = new Array(10000000).join('x'); //10mb
console.log('created object',data);
}
function render() {
const placeToRender = document.getElementById('place-to-render');
placeToRender.innerHTML = data;
console.log('rendered');
}
document.getElementById('btn-load').addEventListener('click', createBigString);
document.getElementById('btn-render').addEventListener('click', render);
如本答案所述
内存占用列与任务管理器或活动监视器中进程的内存列报告的 MB 数相匹配。
这意味着从操作系统获取的实际 RAM 用于 chrome 上的这个特定选项卡。在chrome任务管理器中可以看到。
我做的记忆测试(隐身):
data
在创建字符串(并将其分配给全局变量)后,我记录了堆快照。
- 堆快照为 11MB,
- 内存占用值为 51mb(拍摄快照后)。
然后我点击渲染字符串按钮,在字符串加载到屏幕后,我拍摄了另一个快照。
- 堆快照为 1MB。
- 内存占用惊人地上升到 222mb。(在一个节点中渲染 10mb 字符串时有 173mb 的差异),并且它保持这样,在手动 GC 后它不会下降。
问题:
- 所以我想知道为什么尽管字符串的大小只有 10mb,但内存占用量却有如此大的飞跃?
- 除了 JS 内存 + 媒体文件 + DOM 节点的总和之外,内存 FP 究竟包含什么?
- 与实时 JS 内存相比,是否有任何地方可以阅读有关内存占用空间分配方式和分配因素的信息?
- 有什么性能工具可以用来分析内存占用吗?
- 而且我不确定为什么实时 JS 的第二个快照从 10mb 变为 1mb,如果这些值仍然保存在全局
data
变量中,因此 GC 不应该清理它,对吗?
解决方案
为什么尽管字符串的大小只有 10mb,但内存占用却有如此大的飞跃?
在屏幕上绘制一个包含 1000 万个字符的字符串所需的像素需要远远超过 10 MB。
除了 JS 内存 + 媒体文件 + DOM 节点的总和之外,内存 FP 究竟包含什么?
整个渲染器进程的内存。在我的脑海中,包括各种库、字体、作为渲染过程结果的“图片”,以及用于正在进行的任务的各种临时内存。
不幸的是,我不知道有任何文档或工具可以了解更多关于这些细节的信息;当然,这并不意味着不存在(参见例如 wOxxOm 的评论)。
为什么实时 JS 的第二个快照从 10mb 变为 1mb,如果值仍然保存在全局数据变量中,因此 GC 不应该清理它,对吗?
是的,GC 没有收集字符串。字符串的后备存储(即实际字符)可以在 V8 和 Blink 之间来回传递。在这种情况下,显然字符内容被转移到了 Blink 的责任,因此它们不再是 JavaScript 堆的一部分(尽管String
JS 堆上的对象仍然引用它们),但它们仍然是整个过程的一部分内存占用。
推荐阅读
- reactjs - Gatsby 应用程序部署到 Netlify 问题
- java - 如何在 CoreNLP TokenRegex 模式中转义正则表达式特殊字符?
- c# - 当前上下文中不存在默认 HTTP 标头 IIS 7“MvcHandler”
- ios - 如何让 ImageMagick 库与 Swift 4/iOS 11 一起使用?
- r - R中的列表:实际发生了什么?
- wordpress - 无法使用 WP CLI 安装插件
- javascript - PHP 可以读取第 3 方 URL,而 Javascript 则不能。为什么?
- r - ggplot 中的响应式注释 - 用变化的形状和文本注释图形
- javascript - 改变正在发生的盒子的速度(DOM“改变”事件相关)
- python - 使用 pip 安装 javabridge 的编译器错误