【问题标题】:OutOfMemoryError with free memory availableOutOfMemoryError 有可用内存
【发布时间】:2012-11-07 12:55:28
【问题描述】:

我有一个使用 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

【问题讨论】:

    标签: java memory-leaks


    【解决方案1】:

    内存分配失败时会出现OutOfMemoryError。

    这可能发生在

    • 内存不足。
    • 您的 GC 车削参数阻止它使用所有内存。例如为未满的代设置最小尺寸。
    • 您分配了一大块内存。失败后,您仍然有空闲内存,只是不足以分配大块。
    • 你会得到一个 OutOfMemoryError,它不适用于堆,例如PermGen 或直接内存或虚拟内存(用于线程等)

    【讨论】:

    • +1 - 另一种情况是没有足够的内存用于新的线程堆栈。
    • 我认为这是虚拟内存不足,但也可能是交换空间不足。
    • 另一种可能性是您的堆中充满了无法收集的无法访问的对象,因为至少有一个线程持有“GC locker”互斥锁(例如,当 JNI 代码使用 GetPrimitiveArrayCritical 时持有该互斥锁)。虽然持有此锁,但 Hotspot 似乎从未执行任何 GC。
    【解决方案2】:

    除了 Peter Lawrey 的出色回答之外,您还遇到了“已达到 GC 开销限制”错误。

    当 JVM 没有足够的处理时间来进行垃圾收集或 GC 占用了过多的总可用处理能力时,就会发生这种情况。主要发生在您有大量寿命很短的对象,加上 CPU 占用很大的应用程序并且没有足够的平均可用堆(最大堆大小 - 长期对象)时。

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

    【讨论】:

      猜你喜欢
      • 2013-12-26
      • 1970-01-01
      • 2017-06-01
      • 1970-01-01
      • 2015-12-03
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      • 2018-09-02
      相关资源
      最近更新 更多