首页 > 解决方案 > 了解 Chrome DevTools 内存性能图中的模式

问题描述

我试图了解如何在使用计时器时防止内存泄漏。我相信 Chrome 开发工具性能选项卡(我仍在学习此功能)内存图在内存管理方面向我展示了一个糟糕的模式。我相信每次触发 Timer 时都会出现“锯齿”模式。

我有一个简单的测试用例(1. 右键单击​​“timer-adder.html”,2. 单击“预览”以预览加载的 HTML),其中涉及使用构造函数创建用作计时器的对象,在其他每次更新的话,DOM 都会在setInterval回调中更改。

//...
start: function (initialTime, prefixedId) {
        let $display = document.getElementById(prefixedId + '-display');
        if ($display.style.display === 'none') { $display.style.display = 'block'; }
        $display.textContent = TimerHandler.cycle(initialTime);
        $display = null;
        return setInterval(function () {
            this.initialTime--;
            (this.initialTime === 0 && this.pause());
            document.getElementById(prefixedId + '-display').textContent = TimerHandler.cycle(this.initialTime);
        }.bind(this), 1000);
},
/...

尽量减少泄漏的尝试,尽管与我认为手头的问题没有直接关系:

我认为不好的模式: 查看 imgur.com 上的帖子(可缩放)

公平的内存使用会转化为显示水平线的 DevTools?对于这种副作用,更安全的方法是什么?因为,正如现在的测试一样,我认为从长远来看,多个活动计时器会使内存过载,从而导致性能明显下降。

PS:作为一个新人,我希望这是一个公平的问题介绍。谢谢你。

标签: javascriptmemoryscopegarbage-collectionsetinterval

解决方案


从上一部分可以看出,垃圾收集器能够释放该内存。因此没有内存泄漏。

垃圾收集是一项复杂的任务,这就是为什么 V8 试图最小化 stop-the-world 收集的数量。或者换句话说:它只在需要时清理内存。在你的情况下它没有。仍有足够的可用空间。

如果(显着数量的)内存在 GC 调用中持续存在,那么您确实存在内存泄漏。

分配$display给 null 使其可收集(垃圾收集)。

那只是不必要的。$display不在内部函数中访问,因此在执行后可以进行 gc'ing init。重新分配它不会改变这一点。


推荐阅读