【问题标题】:Is Java GC run when I'm out of memory?当我内存不足时,Java GC 会运行吗?
【发布时间】:2014-10-04 04:59:36
【问题描述】:

我正在用 Java 开发一个基于 Android 的 3D 游戏(不使用 NDK)。 任何游戏的必备条件之一是资源缓存,我可以在其中存储加载的纹理、网格、声音等。

我的计划是开发一个资源缓存来分发对某些资源的弱引用,这样只有缓存本身保持对资源的强引用,这意味着如果我从缓存中删除一个资源,它将被垃圾回收不用我担心。

不过,我很难找到以下问题的答案: 假设我已将资源缓存填充到堆空间几乎已满的程度。我现在想加载一个额外的资源,但是它的内存占用太大以至于它不适合我的可用堆空间。 为了适应新对象的大小,我从缓存中删除了一些条目并加载到新对象中。这可能会导致 OutOfMemory 异常吗? 只要垃圾收集器没有扫描我最近删除的对象,内存就会一直在使用,那么垃圾收集器是否足够聪明,可以运行新的扫描以容纳新分配的对象?

【问题讨论】:

  • 我对 Android 了解不多,但这可能不是一个好主意。 Android 已经 special handles Bitmaps 我会尽可能多地使用它(虽然我不喜欢它)。

标签: java android garbage-collection


【解决方案1】:

JVM 会在抛出 OutOfMemoryError 之前运行 Full GC(它不想抛出 OOME,所以它会尝试一切可能的)。就是这么贴心。

【讨论】:

    【解决方案2】:

    不保证 GC 会运行,尽管它通常会运行。我知道我见过没有 GC 的 OOME,而 GC 可能会有所作为,但这种情况很少见。通常,如果您已取消引用对象并且它们有资格进行 GC,那么当您需要为新对象分配内存时,JVM 会很好地完成它的工作,您会没事的。如果你得到一个 OOME 并且你认为应该有足够的内存可用,那么正确地取消引用对象通常是问题。

    看到这篇文章:

    Is the garbage collector guaranteed to run before Out of Memory Error?

    您也可以请求 GC,但这也不能保证它会运行,而且这可能不是一个好主意。看这篇文章:

    Garbage collector in Android

    【讨论】:

      【解决方案3】:

      [Java Machine specification states(#6.3)] 声明如下:

      OutOfMemoryError: The Java Virtual Machine implementation has run out of either virtual
      or physical memory, and the **automatic storage manager was unable to reclaim enough memory**
      to satisfy an object creation request.
      

      所以 JVM 确实保证它会在抛出 OutOfMemoryError 之前尝试通过 GC 释放内存。

      【讨论】:

        【解决方案4】:

        为了适应新对象的大小,我从缓存中删除了一些条目并加载到新对象中。这可能会导致 OutOfMemory 异常吗?只要垃圾收集器没有扫描我最近删除的对象,内存就会一直在使用,那么垃圾收集器是否足够聪明,可以运行新的扫描以容纳新分配的对象?

        通过删除,我了解您将它们设置为 null 以使它们符合GC 的条件。尽管您已将它们设置为 null,但 GC 可能决定根本不进行内存扫描。现在您可以显式调用System.gc,但GC 将再次在单独的低优先级 线程中运行。而且对象的集合不会立即。现在,一旦您尝试加载大型资源,GC 会发现内存较少,它会开始执行任务以释放尽可能多的内存。但它仍然会抛出OutOfMemory,因为您在尝试加载资源时没有内存。

        【讨论】:

          【解决方案5】:

          我刚刚按照Kayaman之前所说的找到了自己问题的答案:

          Java 虚拟机实现已用完虚拟或物理内存,并且自动存储管理器无法回收足够的内存来满足对象创建请求。

          发现于http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.3

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-02-25
            • 2012-10-27
            • 1970-01-01
            • 1970-01-01
            • 2020-10-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多