【问题标题】:When does Java's garbage collection free a memory allocation?Java 的垃圾收集何时释放内存分配?
【发布时间】:2010-07-23 03:34:42
【问题描述】:

我在 Java 中创建了一个名为 FOO 的对象。 FOO 包含大量数据.. 我不知道说我已经拉入 ram 进行操作的 10 兆字节文本文件。(这只是一个例子)

这显然是一个巨大的空间,我想从内存中释放它。我将 FOO 设置为 NULL。

这会自动释放内存中的空间吗? 或者 加载的文本文件占用的内存会一直持续到自动垃圾回收吗?

【问题讨论】:

标签: java garbage-collection


【解决方案1】:

当您将任何对象的引用设置为null 时,它变为用于垃圾回收。在垃圾收集器实际运行之前,它仍会占用内存。不能保证 GC 何时运行,除非它肯定会在抛出 OutOfMemoryException 之前运行并从无法访问的对象中回收内存。

您可以调用 System.gc() 来请求垃圾回收,但这就是它的本质 - 一个请求。运行由 GC 自行决定。

在某些情况下,使用 WeakReference 会有所帮助。请参阅 Brian Goetz 的 this article

【讨论】:

    【解决方案2】:

    实际上这个对象并没有命名为 FOO。 FOO 是不是对象的变量的名称;该变量包含对对象的引用。可能有几个不同的变量包含对同一对象的引用。

    垃圾收集器通过自动检测无法访问对象来工作:这些是应用程序无法再使用的对象,因为它已经无法挽回地忘记了它们的位置(应用程序可能会访问它拥有的任何对象)引用,包括存储在它可以访问的对象的字段中的引用,等等)。

    当您设置FOO = null 时,假设FOO 在该点包含对该对象的最后一个可访问的引用,那么在以下意义上立即释放内存:在非常时钟在FOO 中设置null 的循环中,对象变得无法访问。因此,垃圾收集器会注意到那个不可达的对象并回收相应的内存块;也就是说,GC 将在下次运行时执行此操作。当然,构成对象的实际位可能会在内存中徘徊一点;但是该块仍然是“空闲的”,因为内存分配器会在可用内存紧张时自动运行 GC。从应用程序的角度来看,对象就像死了一样,相应的内存是空闲的,因为该内存将在下次应用程序需要它时被重用。整个过程是自动的。

    操作系统方面的情况要复杂一些。如果从应用程序的角度来看,无法访问的对象是空闲内存,那么就操作系统而言,它仍然是专用于正在运行的进程的 RAM 块。只有当 GC(即在 OS 级别,进程的一部分)实际运行时,该 RAM 块才可能被归还给 OS,注意到对象不可访问,并屈尊将块归还给 OS . GC 何时运行很大程度上取决于 GC 技术以及应用程序如何分配对象;此外,一些 GC 根本不会将块归还给 OS(GC 知道它释放的块,内存分配器会随意重用它,但不会重用其他进程)。

    System.gc() 是对 VM 的提示,以便它现在运行 GC。形式上,它只是一个提示,VM 可以随意忽略它。在实践中,它会运行 GC,除非 VM 被指示不遵守此类命令(对于 Sun 的 JVM,这是一个特定命令行标志的问题)。即使 GC 运行,它也不一定将内存归还给操作系统。 System.gc() 不是很有用。

    【讨论】:

      【解决方案3】:

      设置foo = null; 并不意味着foo 将立即被垃圾回收。相反,如果可以的话,它将在 GC 下一次运行时被收集。当foo 被收集时,它拥有唯一引用的任何对象也将有资格被收集并因此被收集。

      【讨论】:

        【解决方案4】:

        请注意,即使调用 System.gc() 也不能保证 JVM 会立即执行此操作。

        System.gc() 只是一个请求,不能保证立即生效。

        【讨论】:

          【解决方案5】:

          无法保证 JVM 会立即执行此操作,您可以尝试使用 System.gc()

          强制执行

          【讨论】:

          • 调用System.gc() 不会强制进行垃圾回收。
          • 我的意思是强制它,但不能保证它会这样做
          【解决方案6】:

          垃圾收集器将在您“销毁”引用后释放内存。 i.3 将对象引用设置为空。您可以使用强制垃圾回收选项,但应谨慎使用。垃圾收集器设计为使用优化的调度,因此调用 System.gc() 可能会破坏节奏,并且由于不必要的任务切换可能会降低性能。

          或者,您可以考虑一种不将大量数据加载到内存中的方法。如果您可以通过改进代码来获得这一点,那就更好了。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-05-15
            • 1970-01-01
            • 1970-01-01
            • 2021-11-22
            • 1970-01-01
            • 2012-04-08
            • 2011-12-03
            • 2012-06-12
            相关资源
            最近更新 更多