【发布时间】:2015-06-14 02:16:06
【问题描述】:
我正在阅读有关 Java 中的垃圾收集和终结的信息,并尝试了一个示例。点击按钮 1,内存跳起来。但是当我单击按钮 2 时,内存并没有释放已用空间! 我做错了什么以及如何从未使用的对象中释放内存?
据我所知(我可能错了):
- 当同一个变量被反复实例化时,旧对象将被销毁。
- 当我将变量设置为 null 时,旧对象将被销毁。
- 数组单元格是空值。当父数组对象没有引用它的变量时,它们将被销毁。
- 如何释放集合?数组规则如何应用?
代码:
public class Memory extends javax.swing.JFrame {
Object[] object;
private void Button1ActionPerformed(java.awt.event.ActionEvent evt) {
object = new Object[10240000];
}
private void Button2ActionPerformed(java.awt.event.ActionEvent evt) {
object = null;
System.gc();
System.runFinalization();
//OR
System.runFinalization();
System.gc();
}
}
【问题讨论】:
-
即使 GC 收集到一个对象,Java 仍可能保留内存以更有效地分配新对象。
-
你怎么知道没有空间被释放?很可能 GC 完成了它的工作(可用堆空间增加了),但 JVM 本身并没有向操作系统释放内存......
-
此外,将变量设置为 null 并不是使对象符合 GC 条件的原因。当一个对象不能被来自根的任何强引用链(线程堆栈或静态变量)访问时,它就有资格进行 GC。例如,如果您执行
Object a = new Object(); b = a; a = null;,则a引用的对象将不会被GC,因为b仍然引用它。 -
使用 jvisualvm(与 JDK 捆绑)查看您的空闲堆很可能会增加。 (或启用 GC 日志记录(-verbose:gc))。这样你就可以验证GC是否真的清理干净了。
标签: java memory garbage-collection finalize