在Java中有没有办法释放内存,类似于C的free()
函数?或者,将对象设置为null并依赖GC是唯一的选择吗?
发布于 2009-10-14 19:50:14
似乎没有人明确提到将对象引用设置为null
,这是一种“释放”内存的合法技术,您可能会考虑使用它。
例如,假设您在一个方法的开头声明了一个List<String>
,该方法的大小增长到非常大,但直到方法中途才需要它。此时,您可以将列表引用设置为null
,以允许垃圾收集器在方法完成之前潜在地回收此对象(并且该引用无论如何都会超出范围)。
请注意,我在实际中很少使用这种技术,但在处理非常大的数据结构时,它是值得考虑的。
发布于 2014-01-26 04:28:26
*“我个人依赖于将变量置为空作为将来正确删除的占位符。例如,在实际删除(使其为空)数组本身之前,我会花时间将数组的所有元素置为空。”
这是不必要的。Java GC的工作方式是查找没有引用它们的对象,所以如果我有一个引用(=变量)a指向它的对象x,GC不会删除它,因为有一个对该对象的引用:
a -> x
如果您将a设为空,则会发生以下情况:
a -> null
x
所以现在x没有指向它的引用,将被删除。当您将a设置为引用不同于x的对象时,也会发生同样的事情。
因此,如果你有一个引用对象x,y和z的数组arr和一个引用数组的变量a,它看起来是这样的:
a -> arr -> x
-> y
-> z
如果您将a设为空,则会发生以下情况:
a -> null
arr -> x
-> y
-> z
因此,GC发现arr没有对它的引用集并将其删除,这就给出了这个结构:
a -> null
x
y
z
现在GC找到x、y和z并将其删除。清空数组中的每个引用不会带来任何好处,它只会耗尽代码中的CPU时间和空间(也就是说,它不会造成更大的伤害。GC将仍然能够以它应该执行的方式执行)。
发布于 2014-04-15 20:03:51
为了扩展Yiannis和Hot的回答和评论(对不起,我还不能评论!),你可以像这个例子一样设置VM选项:
-XX:+UseG1GC -XX:MinHeapFreeRatio=15 -XX:MaxHeapFreeRatio=30
在我的JDK7中,当VM空闲时,如果超过30%的堆在GC之后变得空闲,这将释放未使用的VM内存。您可能需要调优这些参数。
虽然我没有在下面的链接中强调这一点,但请注意,一些垃圾收集器可能不遵守这些参数,并且默认情况下,如果您碰巧有多个内核(因此上面的UseG1GC参数),java可能会为您选择其中一个。
更新:对于java 1.8.0_73,我看到JVM偶尔会释放少量的默认设置。看起来只有在大约70%的堆未使用的情况下才会这样做。不知道如果操作系统的物理内存较低,是否会更积极地释放。
https://stackoverflow.com/questions/1567979
复制相似问题