【问题标题】:How to Clean up This Java Example Memory如何清理这个 Java 示例内存
【发布时间】:2015-06-14 02:16:06
【问题描述】:

我正在阅读有关 Java 中的垃圾收集和终结的信息,并尝试了一个示例。点击按钮 1,内存跳起来。但是当我单击按钮 2 时,内存并没有释放已用空间! 我做错了什么以及如何从未使用的对象中释放内存?

据我所知(我可能错了):

  1. 当同一个变量被反复实例化时,旧对象将被销毁。
  2. 当我将变量设置为 null 时,旧对象将被销毁。
  3. 数组单元格是空值。当父数组对象没有引用它的变量时,它们将被销毁。
  4. 如何释放集合?数组规则如何应用?

代码:

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


【解决方案1】:

System.gc() 只是 JVM 清理内存的建议。它可能会也可能不会接受这个建议。你没有做错任何事。放松。

【讨论】:

  • 在实践中,它通常会做它被要求做的事情,并且在这种情况下可能会做。
【解决方案2】:

Java 最终会清除未使用的对象,这就是垃圾收集器的用途。您不必担心它或为它编写任何代码。

Java 中的 GC 是周期性的,它不是瞬时的,System.gc() 只是建议应该运行 GC,这可能不会发生。

如果您想查看 java GC 的运行情况,您应该尝试运行时间更长的程序,以查看内存和 GC 运行情况。

  1. 当同一个变量被重新初始化的次数越来越多时,旧对象将被销毁。

  2. 当将变量设置为 null 时,旧对象将被销毁

  3. 数组单元格是空值,当父数组对象没有变量可以引用它时,它们应该被销毁

  4. 如何释放集合或应用数组规则?

对所有四点的回答是:垃圾收集器会处理这个问题。

即使垃圾收集器可能确实运行了内存仍然很高的原因是 JVM 占用的内存不仅仅是对象。

【讨论】:

  • 确保询问者知道 GC 定期运行并且它不是瞬时的,并在一段时间内跟踪繁忙的 Java 应用程序中的内存使用情况以更好地了解它。
猜你喜欢
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
  • 2015-02-18
  • 2017-02-18
  • 1970-01-01
相关资源
最近更新 更多