java.lang.OutOfMemoryError超出Java堆空间的GC开销限制?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java.lang.OutOfMemoryError超出Java堆空间的GC开销限制?相关的知识,希望对你有一定的参考价值。

什么java.lang.OutOfMemoryError:Java堆空间意味着该消息意味着应用程序只需要比可用的Java堆空间更多的Java堆空间来正常运行。

什么java.lang.OutOfMemoryError:GC开销限制超出意味着此消息意味着由于某种原因,垃圾收集器花费了过多的时间(默认情况下为进程的所有CPU时间的98%)并且每次运行时恢复的内存非常少(默认情况下为堆的2%)。这在内部也意味着当应用程序只需要比可用的Java堆空间更多的Java堆空间来正常运行时。

所以我的问题是上述两种情况会被触发?

所以这是我的理解,当基于场景抛出特定异常时: -

假设我已经分配了1GB的堆大小。目前使用堆内存为970 MB。线程已启动(JVM不知道它将消耗多少内存)。现在GC可以采取以下步骤之一

1)JVM开始分配内存,然后在一个时间点耗尽1GB内存并抛出java.lang.OutOfMemoryError: Java heap space

2)GC提前运行并尝试释放一些内存,因为它知道当前正在使用的内存接近1 GB分配,Heap。但是,在每次后续运行中,它无法释放超过2%的空间。然后它会抛出java.lang.OutOfMemoryError: GC overhead limit exceeded

我的理解在我的问题中是否正确?

答案

OutOfMemoryError:Java堆空间

即使在执行了所有最后沟渠工作之后,JVM也无法满足分配请求。

超出了OutOfMemoryError GC开销限制

意味着JVM可能能够满足分配请求,但是在最近的过去,它经常需要GC,因此在GCing上花费的CPU时间超过了Java进程使用的总CPU时间的(可配置的)部分。

JVM自我终止,而不是挥之不去的半工作,非常低效的状态,可能只会随着时间的推移而变得更糟。

通常,禁用GC开销OOM只会在几分钟后导致Java堆空间OOM。

它基本上是一种快速失败的机制。

另一答案
java.lang.OutOfMemoryError: Java heap space

原因:无法在Java堆中分配对象。此错误不一定意味着内存泄漏。问题可以像配置问题一样简单,其中指定的堆大小(或者未指定的默认大小)对于应用程序来说是不够的。

java.lang.OutOfMemoryError: GC Overhead limit exceeded

正如你所说,垃圾收集时间过长。它可能是您的应用程序中内存泄漏的副作用。由于泄漏,旧的gen可能已完全填满,因此GC不会释放任何(或非常少)垃圾收集周期。

看看这个oracle article来解决不同类型的内存泄漏问题。

关于你的两个问题,我也认为你的理解是正确的,除非有区别。在第二种情况下触发GC的事件不仅仅是新对象的创建。在特定条件下将触发完整GC。看看这个SE问题。

以上是关于java.lang.OutOfMemoryError超出Java堆空间的GC开销限制?的主要内容,如果未能解决你的问题,请参考以下文章