如何在JavaScript中释放内存


70

我正在使用canvas及其包含大量数据(数百万个整数)的ImageData对象。因此,使用几个阵列已经占用了大量内存(最大300MB)。有没有必要的时候可以释放一些数组的内存的方法?我正在尝试分配undefined给该变量。这样对吗?


您无法使用Javascript管理内存分配或调用垃圾回收器。
Jared Farrish

1
我相信这就是您所能做的。其余的取决于垃圾收集器。
肯·韦恩·范德林德

所以我所能做的就是使用尽可能少的数组?
haynar 2011年

4
您可以分配null而不是undefined
Basile Starynkevitch 2011年

1
可能值得注意的是,由于可以将边界传递给getImageData,因此不必一定要一次处理整个图像数据数组。根据您所执行的操作,它可能会消耗较少的峰值内存来按块处理图像,以便垃圾回收可以在块之间进行。
詹姆斯·克拉克

Answers:


115

如果变量持续存在(例如,它是全局变量或某些持久数据结构的一部分),并且指向的数据很大,并且您希望该数据有资格进行垃圾回收,那么为该变量分配较小的对象是正确的。 undefinednull""将一切正常。您正在执行的操作是清除对大数据的引用,以便可以进行垃圾回收。如果您的javascript中没有其他引用该数据的内容,则可以由垃圾回收器将其释放。如果还有其他引用,则无法释放它。

例如,如果在全局变量中保存了10,000个元素数组:

var largeDataArray = new Array(10000);

并且,您已经用数据填充了大多数元素,然后可以通过为其分配一些其他值来允许该内存有资格进行垃圾回收:

largeDataArray = null;

或者,如果您仍然希望它是一个数组:

largeDataArray = [];

注意:本身超出范围的变量(例如不属于持久闭包的函数中的局部变量)或本身超出范围的对象中的变量不必手动清除。当它们超出范围或删除父对象时,其中包含的数据也将有资格进行垃圾回收。

因此,仅当您明确想要释放持久变量中保存的数据时,才需要清除变量;通常只有在数据量很大或您添加了很多数据时才担心此问题高达数兆字节的数据(与台式机浏览器相比,在智能手机上较低级别的内存使用更为重要)。


thx很好的答案:)如果没有其他新的事实要强调的话
它将

2
deletejavascript中有一个,但是它主要用于删除对象的属性,而不像C ++中的delete那样。您可以在此处阅读有关删除的所有信息。
jfriend00 2011年

1
@haynar,它是运算符,而不是方法:developer.mozilla.org/en/JavaScript/Reference/Operators/delete
Matt Ball

1
largeDataArray.length = 0删除所有元素。largeDataArray = []更改largeDataArray的引用不会删除原始数组,因此执行诸如arrayA = [0,1,2]; arrayB = arrayA; arrayA = []; console.log(arrayA,arrayB)=> [],[0,1,2]
Adam Michalski

2
@AdamMichalski-这里的要点是重新分配任何东西以largeDataArray允许先前的数组有资格进行垃圾回收(如果没有其他引用)。是的,您也可以.length根据情况将其设置为零。
jfriend00

3

JavaScript具有自动内存管理功能。包含不再引用的对象的内存将有资格进行垃圾回收,除非发生内存泄漏。通常不需要手动分配undefined变量。

如果您的程序使用了过多的内存,则应缩小数组以摆脱不再需要的元素。见Array.popArray.shiftArray.splice


42
这是错误的,因为通常不需要手动将undefined分配给变量。如果要释放大变量消耗的内存并且该变量持久(例如,全局对象或某些持久存在的对象的一部分),则释放内存的一种方法是将变量重新分配给很小的对象因此,正在使用的大数据将不再对其具有任何引用,并且可以被垃圾回收。我还没有投票,但是我正在考虑,因为这篇文章在某些情况下是误导性的,而在另一些情况下是错误的。
jfriend00 2011年

不建议过分依赖垃圾收集器。在内存不足的情况下,垃圾收集器会积极尝试释放内存。即使垃圾收集器已经走了很长一段路,但如此激进的垃圾收集会影响您的性能。
Surender Thakran 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.