JavaScript内存管理和垃圾回收

3

我已经阅读了很多关于Javascript内存管理的堆栈文章和博客帖子。

我的理解是,在给定的作用域内,变量在所有对它们的引用都被删除时被标记为清除。大多数"内存泄漏"似乎涉及变量通过作用域链接,或链接到DOM元素,进而防止它们被垃圾收集。

然后,我试图理解为什么这三个代码段在Chrome和Firefox中需要相同的RAM使用情况:

<html>
<body>
    <script>
        var bigString1=new Array(1000).join(new Array(2000).join("XXXX1"));
        var bigString2=new Array(1000).join(new Array(2000).join("XXXX2"));
        var bigString3=new Array(1000).join(new Array(2000).join("XXXX3"));
        var bigString4=new Array(1000).join(new Array(2000).join("XXXX4"));
        var bigString5=new Array(1000).join(new Array(2000).join("XXXX5"));
    </script>
</body>
</html>

这只是在窗口范围内创建了变量,所以它们驻留在内存中。

<html>
<body>
    <script>
        var bigString1=new Array(1000).join(new Array(2000).join("XXXX1"));
        var bigString2=new Array(1000).join(new Array(2000).join("XXXX2"));
        var bigString3=new Array(1000).join(new Array(2000).join("XXXX3"));
        var bigString4=new Array(1000).join(new Array(2000).join("XXXX4"));
        var bigString5=new Array(1000).join(new Array(2000).join("XXXX5"));
        bigString1 = null;
        bigString2 = null;
        bigString3 = null;
        bigString4 = null;
        bigString5 = null;
    </script>
</body>
</html>

然而,从内存中删除它们并不会减少内存使用量。

<html>
<body>
    <script>
    var test = function(){
        var bigString1=new Array(1000).join(new Array(2000).join("XXXX1"));
        var bigString2=new Array(1000).join(new Array(2000).join("XXXX2"));
        var bigString3=new Array(1000).join(new Array(2000).join("XXXX3"));
        var bigString4=new Array(1000).join(new Array(2000).join("XXXX4"));
        var bigString5=new Array(1000).join(new Array(2000).join("XXXX5"));
        bigString1 = null;
        bigString2 = null;
        bigString3 = null;
        bigString4 = null;
        bigString5 = null;
    }
    test();
    </script>
</body>
</html>

即使将它们放在完成的范围内,也不能从内存中删除它们。
自己尝试一下。观察活动监视器中的内存分配情况。所有三个HTML文件都分配并保留了完全相同的RAM。
有谁能帮忙指出我在这里缺少的信息?我们如何确切地释放Javascript中未使用数据的内存?
例如,如果我继续运行…
(function(){ var bigString1=new Array(1000).join(new Array(2000).join("XXXX3")); })();

浏览器每次都会分配约20mb的RAM,一遍又一遍地重复。我可以让电脑闲置几个小时,但RAM从未被释放。如果RAM是保留的,但被清除了,那么反复运行相同的命令只会一遍又一遍地使用同一块内存空间。


1
我不认为“对象被垃圾回收 === 空闲内存”。但是,当您执行几次时,您可以看到它是否泄漏。 - Bergi
1个回答

1

很可能Chrome正在保留分配的内存以便稍后重用。您应该能够在已分配但未使用的内存中创建新数组。

更新 我刚刚在Linux Mint上使用Chrome 23进行了测试。

运行中

(function(){ var bigString1=new Array(1000).join(new Array(2000).join("XXXX3")); })(); 

在页面原有使用的基础上分配大约20MB。在控制台中反复垃圾邮件片段不会进一步增加内存使用量。大约30秒后,内存将被回收。


我曾经想象过这就是正在发生的事情,但为什么每当我重复运行(function(){ var bigString1=new Array(1000).join(new Array(2000).join("XXXX3")); })();时,会分配大约20MB的新内存空间并且从未被回收? - BishopZ
它是每次分配还是只在第一次运行时分配? - Alex
说实话,我已经运行了很多次测试。有时它看起来像答案提供者建议的那样工作,但大多数情况下,每次运行命令都会分配一个新的20mb。我这里有一个Chrome选项卡已经超过一个小时使用600mb的RAM。我所做的就是一遍又一遍地在控制台中运行该命令。再运行一次,它就会上升到620mb。我正在使用Mac OSX,使用Chrome 23和FF16。 - BishopZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接