具有可用内存的OutOfMemoryError

时间:2012-11-07 12:55:28

标签: java memory-leaks

我有一个应用程序,它使用java线程池在后台执行一些繁重的处理。

线程池配置为记录执行期间发生的异常

public enum ExceptionLogger implements Thread.UncaughtExceptionHandler {
    INSTANCE;

    private static final Logger log = LoggerFactory.getLogger(ExceptionLogger.class);

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        log.error("Exception occurred at thread " + t.getName() + "\n", e);
    }
  }

在我的应用程序的日志中,我随机获取java.lang.OutOfMemoryError: Java heap space,但如果我使用Runtime.getRuntime().freeMemory()记录内存使用情况,我可以看到大量可用的堆空间。

此外,应用程序在我收到此异常后继续工作。

使用此消息获取OutOfMemoryError是否还有其他原因?

2 个答案:

答案 0 :(得分:3)

当内存无法分配时,您将收到OutOfMemoryError。

这可能发生在

  • 你内存不足。
  • 您的GC转向参数会阻止其使用所有内存。例如为未满的世代设定最小尺寸。
  • 你分配了一大块内存。在此失败后,您仍然可以获得空闲内存,但不足以分配大块。
  • 你得到的OutOfMemoryError不适用于堆,例如PermGen或直接内存或虚拟内存(用于线程等)

答案 1 :(得分:1)

除了Peter Lawrey的优秀答案外,您还有“达到GC开销限制”的错误。

当JVM没有足够的处理时间来进行垃圾收集或GC占用总的可用处理能力时,会发生这种情况。主要发生在大量非常短暂的对象与CPU饥饿的应用程序相结合且没有足够的平均可用堆(最大堆大小 - 长寿命对象)时。

这方面的解决方案各不相同,但通常意味着您必须限制CPU消耗(在您的情况下,线程数)和/或增加堆大小。