JavaScript setInterval() 方法会导致内存泄漏吗? [英] Does JavaScript setInterval() method cause memory leak?

查看:119
本文介绍了JavaScript setInterval() 方法会导致内存泄漏吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前正在开发一个基于 JavaScript 的动画项目.

我注意到,正确使用 setInterval()setTimeout() 甚至 requestAnimationFrame 会在没有我请求的情况下分配内存,并导致频繁的垃圾收集调用.更多 GC 调用 = 闪烁 :-(

例如;当我通过在 Google Chrome 中调用 init() 执行以下简单代码时,内存分配 + 垃圾收集在前 20-30 秒内没问题...

函数 init(){var ref = window.setInterval(function() { draw(); }, 50);}函数绘制(){返回真}

不知何故,在一分钟左右的时间内,分配的内存开始奇怪地增加!由于 init() 只调用一次,分配的内存大小增加的原因是什么?

(上传的 chrome 屏幕截图)

注意#1:是的,我曾尝试在下一个 setInterval() 之前调用 clearInterval().问题依旧!

注意 #2:为了隔离问题,我将上面的代码保持简单和愚蠢.

解决方案

函数 init(){var ref = window.setInterval(function() { draw(); }, 50);}函数绘制(){console.log('你好');}在里面();

显然 setTimeoutsetInterval 不是 Javascript 的正式组成部分(因此它们不是 v8 的一部分).实现留给实现者.建议你看看setInterval等的实现在 node.js 中

Currently developing a JavaScript based animation project.

I have noticed that, proper use of setInterval(), setTimeout() and even requestAnimationFrame allocates memory without my request, and causes frequent garbage collection calls. More GC calls = flickers :-(

For instance; when I execute the following simple code by calling init() in Google Chrome, memory allocation + garbage collection is fine for the first 20-30 seconds...

function init()
{
    var ref = window.setInterval(function() { draw(); }, 50);
}

function draw()
{
    return true
}

Somehow, within a minute or so, starts a strange increase in allocated memory! Since init() is called only for once, what is the reason for the increase in allocated memory size?

(Edit: chrome screenshot uploaded)

NOTE #1: Yes, I have tried calling clearInterval() before the next setInterval(). Problem remains the same!

NOTE #2: In order to isolate the problem, I'm keeping the above code simple and stupid.

解决方案

EDIT: Yury's answer is better.


tl;dr IMO there is no memory leak. The positive slope is simply the effect of setInterval and setTimeout. The garbage is collected, as seen by sawtooth patterns, meaning by definition there is no memory leak. (I think).

I'm not sure there is a way to work around this so-called "memory leak." In this case, "memory leak" is referring to each call to the setInterval function increasing the memory usage, as seen by the positive slopes in the memory profiler.

The reality is that there is no actual memory leak: the garbage collector is still able to collect the memory. Memory leak by definition "occurs when a computer program acquires memory but fails to release it back to the operating system."

As shown by the memory profiles below, memory leak is not occurring. The memory usage is increasing with each function call. The OP expects that because this is the same function being called over and over, there should be no memory increase. However, this is not the case. Memory is consumed with each function call. Eventually, the garbage is collected, creating the sawtooth pattern.

I've explored several ways of rearranging the intervals, and they all lead to the same sawtooth pattern (although some attempts lead to garbage collection never happening as references were retained).

function doIt() {
    console.log("hai")
}

function a() {
    doIt();
    setTimeout(b, 50);
}
function b() {
    doIt();
    setTimeout(a, 50);
}

a();

http://fiddle.jshell.net/QNRSK/14/

function b() {
    var a = setInterval(function() {
        console.log("Hello");
        clearInterval(a);
        b();                
    }, 50);
}
b();

http://fiddle.jshell.net/QNRSK/17/

function init()
{
    var ref = window.setInterval(function() { draw(); }, 50);
}
function draw()
{
    console.log('Hello');
}
init();

http://fiddle.jshell.net/QNRSK/20/

function init()
{
    window.ref = window.setInterval(function() { draw(); }, 50);
}
function draw()
{
    console.log('Hello');
    clearInterval(window.ref);
    init();
}
init();​

http://fiddle.jshell.net/QNRSK/21/

Apparently setTimeout and setInterval are not officially parts of Javascript (hence they are not a part of v8). The implementation is left up to the implementer. I suggest you take a look at the implementation of setInterval and such in node.js

这篇关于JavaScript setInterval() 方法会导致内存泄漏吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆