博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OOM问题定位
阅读量:6083 次
发布时间:2019-06-20

本文共 1949 字,大约阅读时间需要 6 分钟。

hot3.png

一:堆内存溢出

Java创建的对象一般都是分配在堆中,如果是由于过期对象没能回收(内存泄漏)或者对象过多导致放不下(内存溢出),一般报错:

Exception in thread \"main\" java.lang.OutOfMemoryError: Java heap space        at java.util.Arrays.copyOf(Arrays.java:2760)        at java.util.Arrays.copyOf(Arrays.java:2734)        at java.util.ArrayList.ensureCapacity(ArrayList.java:167)        at java.util.ArrayList.add(ArrayList.java:351)        at test.java.VM.OOM.HeapOOM.main(HeapOOM.java:19)

 解决这部分的异常,重点是通过内存映像分析工具分析堆的转储快照,确定异常是由于内存泄漏还是内存溢出导致的。

     如果是内存泄漏导致的,则进一步查看泄漏对象到GCRoots的引用链,观察泄漏对象是通过怎样的路径与GCRoots相关联并导致垃圾回收器无法回收的;

     如果是内存溢出导致的,则检测堆的大小参数(Xmx、Xms)看看能否再调大,检测是否有某些对象生命周期过长。

解决参考:https://my.oschina.net/LucasZhu/blog/1820830

二:方法区溢出(Java8之前)

    方法区主要存放类的信息、静态变量、常量池等,当常量池溢出或者不停地有类动态创建并加载时,方法区也能产生OOM。

 报错信息: 

Exception in thread \"main\" java.lang.OutOfMemoryError: PermGen space

      拓展:String.intern():如果字符串常量池已经包含一个等于此string对象的字符串,则返回该字符串;否则,将次string对象的内容加入到常量池中,并返回该对象的引用。

解决参考:

三:栈溢出(虚拟机栈、本地方法栈)

栈的异常有两种:

   JVM在执行方法时就会创建方法栈,方法的递归、调用等使得其他方法不停地入栈,其他方法执行完毕就会弹出栈帧。当一个方法栈的深度大于JVM所允许的深度时就会报StackOverFlow;一般,出现StackOverFlow时就要检查代码是否有无穷递归的情况出现了。

stack length:1007Exception in thread \"main\" java.lang.StackOverflowError        at test.java.VM.OOM.JavaVMStackOF.stackLeak(JavaVMStackOF.java:13)        at test.java.VM.OOM.JavaVMStackOF.stackLeak(JavaVMStackOF.java:14)

 栈空间扩展时没有足够的内存则报OutOfMemory。

在java8中,Metaspace的出现,使我们现在不会再遇到java.lang.OutOfMemoryError: PermGen问题,但是我们要记住,这个新特性并不会使类加载导致的内存泄露就此消失。

(一)Metaspace的简单介绍 

(1)内存模型:大部分类元数据都在本地内存分配,用于描述类元数据的“klasses“已经被移除。 
(2) 容量:默认情况下只受本地内存限制,但是我们可以限制。

1,首先不进行任何设置(需要保证堆大小),运行得到下面的截图 

è¿éåå¾çæè¿°

Metaspace进行了动态扩展,本地内存达到了300多M,加载超过5万个类后还没有出现OOM事件。接下来我们限定一下

2,虚拟机参数配置如下:-Xmx2g -Xms2g -Xmn1g -XX:+PrintGCDetails  -XX:MaxMetaspaceSize=128m,运行得到下面的截图 

è¿éåå¾çæè¿°

可以看出,此时Metaspace被耗尽,将会抛出OOM事件。这里要注意MaxPermSize的区别,MaxMetaspaceSize并不会在jvm启动的时候分配一块这么大的内存出来,而MaxPermSize是会分配一块这么大的内存的。

那么问题来了,如果我们不设置MaxMetaspaceSize,那么我们能用到系统的全部内存吗?? 

metaspace很可能因为被无止境使用而被OS Kill,所以一般还是设置比较好。

 

 

 

 

 

 

 

转载于:https://my.oschina.net/LucasZhu/blog/1821111

你可能感兴趣的文章
Android学习之BMI1.0
查看>>
PureFlex System成为IT架构优化的根基
查看>>
word精华编号篇之一自动编号
查看>>
centos 安装 nginx-mysql-redis
查看>>
C语言实现直接插入排序,冒泡排序以及二分查找(巩固理解记忆)
查看>>
sqoop相关整理记录
查看>>
Solr基础教程之Schema.xml(二)
查看>>
给控件添加长按弹出菜单(上下文菜单,又叫contextMenu)
查看>>
傻瓜式 Material Design 风格矢量图标生成器
查看>>
Nodejs创建HTTPS服务器
查看>>
ubuntu12.04 安装sublime text 2及插件。
查看>>
AFNetworking、MKNetworkKit和ASIHTTPRequest比较
查看>>
Impala 表使用 Avro 文件格式(翻译)
查看>>
http中返回错误代码的意思
查看>>
Spring – 开发环境 – 手动配置
查看>>
!==和!=有什么区别(js php)
查看>>
python入门神图
查看>>
我的友情链接
查看>>
[一文一命令]ls命令详解
查看>>
EBS FORM 失效工具栏按钮
查看>>