是什么原因导致OutOfMemoryError?

发生以下情况之一时,可能会引发OutOfMemoryError

通常可以从错误消息中OutOfMemoryErrorOutOfMemoryError的根本原因。 让我们研究每种情况的细节。

JVM耗尽了本机内存

这基本上意味着分配给JVM的内存量已用完。 32位JVM的最大进程大小约为3.5 – 4 GB。 如果超过它,将OutOfMemoryError 。 即使在64位JVM中,当JVM请求更多内存时,操作系统也可能根本没有足够的内存。 请看以下片段:

for (int i = 0; true; ++i) { 
  new Thread() { 
    public void run() { 
      try { 
         Thread.sleep(1000000); 
      } catch(InterruptedException e) { } 
    } 
   }.start(); 

   System.out.println("Thread"; + i + "created"); 
}

在我的笔记本上(带有Java 1.8.0_112的64位Mac OS X 10.11.6),在创建2023个线程之后,JVM崩溃了:

Thread 2021 created
Thread 2022 created
Thread 2023 created
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread

Java堆内存不足

这个很明显。 分配了太多对象,因此它们不适合为JVM配置的堆空间。 增大堆大小听起来像是一种解决方案,但是如果它是由内存泄漏引起的,则只会推迟OutOfMemoryError 。 错误消息非常清楚:

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

PermGen或Metaspace内存不足

PermGen(Java 7和更早版本)的最大大小有限。 这意味着如果加载了太多的类,PermGen可能会填满,并且将引发OutOfMemoryError 。 增加最大PermGen大小应该会有所帮助。 Java 8没有PermGen,但是有Metaspace。 默认情况下,它具有无限制的最大大小,因此,只要不通过MaxMetaspaceSize标志设置限制,就不应引发该错误。 要诊断由PermGen或Metaspace引起的OutOfMemoryError ,应检查错误消息:

Exception in thread “main” java.lang.OutOfMemoryError: PermGen space
Exception in thread “main” java.lang.OutOfMemoryError: Metaspace

JVM花太多时间试图收集垃圾

这是最棘手的问题–当GC花太多时间收集垃圾而导致的结果太少且进一步的应用程序执行毫无意义时,将引发OutOfMemoryError 。 换句话说,必须满足以下所有条件

  • GC中花费了超过98%的时间(98%是默认值,可以被GCTimeLimit=N覆盖)
  • 在完整GC期间,只有不到2%的堆被回收(再次,2%是默认值,可以被GCHeapFreeLimit=N覆盖)。
  • 前面提到的两个条件都适用于五个连续的完整GC周期
  • UseGCOverheadLimit标志未禁用(true为默认值)

运行完整的GC意味着JVM总是耗尽内存。 如果花费了98%的时间来释放仅2%的堆,则意味着CPU几乎完全忙于GC,几乎无法完成任何应用程序逻辑。 这就是为什么放弃并抛出OutOfMemoryError并显示以下消息的原因:

Exception in thread “main” java.lang.OutOfMemoryError: GC overhead limit exceeded

翻译自: https://www.javacodegeeks.com/2017/08/what-causes-outofmemoryerror.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值