为什么 chrome 任务管理器内存占用显着增加 (170mb) 仅在一个 div 的 innerHTML 中呈现仅 10mb 的字符串?
Why chrome task manager memory footprint increases dramatically(170mb) on rendering just 10mb string in only one div's innerHTML?
我做了一个小测试,我在点击按钮时创建了一个 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);
如本文所述
The Memory Footprint column matches the number of MB reported for the Memory column of the process within the Task Manager or Activity Monitor.
表示 chrome 上此特定选项卡从 OS 中获取的实际 RAM。
可以在chrome任务管理器中看到。
我做的记忆测试(隐身):
我在创建字符串(并将其分配给全局变量 data
)后记录了一个堆快照。
- 堆快照为 11MB,
- 内存占用值为 51mb(拍摄快照后)。
然后我点击渲染字符串按钮,在字符串加载到屏幕后我又拍了一张快照。
- 堆快照为 1MB。
- 内存占用惊人地一路上升到 222mb。 (在一个节点中渲染 10mb 的字符串时有 173mb 的差异),它保持这样,在手动 GC 后它不会下降。
问题:
- 所以我想知道为什么字符串的大小只有10mb,但内存占用却有这么大的飞跃?
- 除了JS内存+媒体文件+DOM个节点的总和外,内存FP到底包含什么?
- 与实时 JS 内存相比,是否有任何地方可以了解内存占用的分配方式和因素?
- 有没有我可以用来分析内存占用的性能工具?
- 而且我不确定为什么实时 JS 的第二个快照从 10mb 变为 1mb,如果值仍然保存在全局
data
变量中,因此 GC 不应该清理它,我我对吗?
why there is such a big leap in memory footprint although the size of the string is only 10mb ?
在屏幕上绘制包含 1000 万个字符的字符串所需的像素需要超过 10 MB。
What exactly does the memory FP contain beside the sum of the JS memory + media files + DOM Nodes ?
整个渲染器进程的内存。在我的脑海中,包括各种库、字体、作为渲染过程结果的“图片”,以及用于正在进行的任务的各种临时内存。
遗憾的是,我不知道有任何文档或工具可以详细了解这些细节;当然,这并不意味着 none 存在(参见 wOxxOm 的评论)。
why the second snapshot of the live JS went from 10mb to 1mb, if still the values are saved on the global data variable, therefore GC should not clean it, am I right?
是的,GC 没有收集字符串。字符串的后备存储(即实际字符)可以在 V8 和 Blink 之间来回传递。在这种情况下,显然字符内容已转移给 Blink 的责任,因此它们不再是 JavaScript 堆的一部分(尽管 JS 堆上的 String
对象仍然引用它们),但是它们仍然是进程整体内存占用的一部分。
我做了一个小测试,我在点击按钮时创建了一个 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);
如本文所述
The Memory Footprint column matches the number of MB reported for the Memory column of the process within the Task Manager or Activity Monitor.
表示 chrome 上此特定选项卡从 OS 中获取的实际 RAM。 可以在chrome任务管理器中看到。
我做的记忆测试(隐身):
我在创建字符串(并将其分配给全局变量 data
)后记录了一个堆快照。
- 堆快照为 11MB,
- 内存占用值为 51mb(拍摄快照后)。
然后我点击渲染字符串按钮,在字符串加载到屏幕后我又拍了一张快照。
- 堆快照为 1MB。
- 内存占用惊人地一路上升到 222mb。 (在一个节点中渲染 10mb 的字符串时有 173mb 的差异),它保持这样,在手动 GC 后它不会下降。
问题:
- 所以我想知道为什么字符串的大小只有10mb,但内存占用却有这么大的飞跃?
- 除了JS内存+媒体文件+DOM个节点的总和外,内存FP到底包含什么?
- 与实时 JS 内存相比,是否有任何地方可以了解内存占用的分配方式和因素?
- 有没有我可以用来分析内存占用的性能工具?
- 而且我不确定为什么实时 JS 的第二个快照从 10mb 变为 1mb,如果值仍然保存在全局
data
变量中,因此 GC 不应该清理它,我我对吗?
why there is such a big leap in memory footprint although the size of the string is only 10mb ?
在屏幕上绘制包含 1000 万个字符的字符串所需的像素需要超过 10 MB。
What exactly does the memory FP contain beside the sum of the JS memory + media files + DOM Nodes ?
整个渲染器进程的内存。在我的脑海中,包括各种库、字体、作为渲染过程结果的“图片”,以及用于正在进行的任务的各种临时内存。
遗憾的是,我不知道有任何文档或工具可以详细了解这些细节;当然,这并不意味着 none 存在(参见 wOxxOm 的评论)。
why the second snapshot of the live JS went from 10mb to 1mb, if still the values are saved on the global data variable, therefore GC should not clean it, am I right?
是的,GC 没有收集字符串。字符串的后备存储(即实际字符)可以在 V8 和 Blink 之间来回传递。在这种情况下,显然字符内容已转移给 Blink 的责任,因此它们不再是 JavaScript 堆的一部分(尽管 JS 堆上的 String
对象仍然引用它们),但是它们仍然是进程整体内存占用的一部分。