【问题标题】:Why heap memory usage keeps on going up?为什么堆内存使用率不断上升?
【发布时间】:2019-10-08 01:52:31
【问题描述】:

在下面的代码 sn-p 中,我没有向 DOM 添加任何新内容,也没有创建任何动态数据类型。我也不会增加数组大小或任何东西。然而,当您在 Chrome 中运行代码(必须托管或本地托管)时,

 performance.memory.usedJSHeapSize 

不断增加。为什么?

<html>

<body>
    <p id="memory" style="position: fixed; top:10px; left:10px; font-size: 1.5em;"></p>
    <script>
        setInterval(() => {
            document.getElementById("memory").innerHTML = performance.memory.usedJSHeapSize;
        }, 300);

    </script>
</body>

</html>

它还托管给您查看(在 Chrome 或 Opera 中打开):

http://appsdepo.com/temp/memory_leak.html

【问题讨论】:

    标签: javascript google-chrome memory-leaks v8


    【解决方案1】:

    该代码中至少有两个分配:

    (1) performance.memory 每次调用时都会创建一个新对象。它是在本机代码中实现的,但 JavaScript 等价物大致如下:

    Object.defineProperty(performance.__proto__, "memory", 
                          {get: function() { 
                              return {usedJSHeapSize: ..., 
                                      totalJSHeapSize: ...,
                                      ...: ...};
                          });
    

    (2) usedJSHeapSize 返回一个数字,但您将该值分配给需要字符串的设置器,因此它被隐式转换为字符串,这是另一种分配。

    请注意,这两者都不是泄漏:当触发垃圾回收时,所有不再需要的旧临时对象都将被清除。只需要一段时间,直到周围有足够的垃圾,Chrome 才会决定进行一些 GC 是对 CPU 的一种很好的利用。

    【讨论】:

    • 我让代码运行了一个小时。内存使用量一直在增加。我想知道为什么CG一个小时没有采取任何行动
    • 可能是因为整体内存消耗还远未达到极限?在那一小时里它增长了多少?您多久查看一次,即您是否注意到它是否在中途释放了一些内存,然后从产生的较低值恢复增长? FWIW,您可以单击 DevTools“内存”选项卡中的垃圾箱图标以强制执行完整的 GC 循环并查看它的作用。
    • 顺便说一句,这些对象不应该在堆栈上分配,还是只有在优化热路径和正常的年轻堆空间之后才完成?
    • V8 通常不会在栈上分配对象,因为这不太符合 JavaScript 的语义。唯一的例外是优化编译器可以证明给定的短期对象不会“逃逸”,在这种情况下,它可以(有时)完全避免分配,并将其各个属性保留在堆栈上。所以是的,通常年轻一代会扮演有效管理短期对象的角色。
    猜你喜欢
    • 2014-04-12
    • 2012-11-01
    • 2017-12-15
    • 2023-03-29
    • 2015-09-15
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-25
    相关资源
    最近更新 更多