如何在JavaScript中释放内存

hay*_*nar 64 javascript arrays memory-management html5-canvas

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

jfr*_*d00 107

如果变量持续存在(例如它是全局的或某些持久数据结构的一部分)并且它指向的数据很大并且您希望该数据符合垃圾收集的条件,那么您可以为该变量分配一些小的内容. undefinednull""将所有的工作.您正在做的是清除对大数据的引用,以便它有资格进行垃圾回收.如果你的javascript中没有其他内容可以引用该数据,那么它可以被垃圾收集器释放.如果其他任何东西都有引用它,那么它就不能被释放.

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

var largeDataArray = new Array(10000);
Run Code Online (Sandbox Code Playgroud)

并且,您已经使用数据填充了大多数元素,然后您可以通过为其分配一些其他值来允许该内存符合垃圾收集条件:

largeDataArray = null;
Run Code Online (Sandbox Code Playgroud)

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

largeDataArray = [];
Run Code Online (Sandbox Code Playgroud)

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

因此,只有当你明确想要释放持久变量中保存的数据时才需要清除变量,并且通常只有在数据很大或你有很多数据添加时才担心这个问题.高达数兆字节的数据(智能手机上的内存使用率低于桌面浏览器).

  • largeDataArray.length = 0 删除所有元素。largeDataArray = [] 更改 largeDataArray 的引用不会删除原始数组,因此执行类似 arrayA = [0, 1, 2]; 的操作 数组B = 数组A;数组A = []; console.log(arrayA, arrayB) => [], [0,1,2] (3认同)
  • 在javascript中有一个`delete`,但它主要用于删除对象的属性,而不是像C++中的delete一样.你可以阅读所有关于删除[这里](http://perfectionkills.com/understanding-delete/). (2认同)
  • @AdamMichalski - 这里的重点是将任何内容重新分配给`largeDataArray`允许前一个数组有资格进行垃圾收集(如果没有其它引用).是的,您也可以根据您的具体情况将`.length`设置为零. (2认同)

Mat*_*all 5

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

如果你的程序使用了太多的内存,你应该缩小数组以摆脱不再需要的元素.见Array.pop,Array.shiftArray.splice.

  • 这是错误的,通常不需要手动将undefined分配给变量.如果你想要释放大变量所消耗的内存并且该变量是持久的(例如全局或某些对象的一部分持续存在),那么释放内存的一种方法是重新分配一个非常小的变量.因此,正在使用的大数据将不再具有任何对它的引用,并且可以被垃圾收集.我还没有投票,但我正在考虑这个问题,因为这篇文章在某些情况下会产生误导,而在其他情况下则会出错. (54认同)
  • 也不建议过度依赖垃圾收集器。如果内存短缺,垃圾收集器会积极尝试释放内存。尽管垃圾收集器已经取得了长足的进步,但如此激进的垃圾收集可能会影响您的性能。 (3认同)