常见的OOM现象和解决办法

Java的内存溢出由于引入了GC的缘故已经少了很多(相对C++少了不少),不过GC也不是万能的,我们使用不当的时候还是会发生OOM现象,由此我们有必要认识一下常见的OOM现象和解决方法。

堆溢出

可以说这种现象是我们碰到最多的一种了,报错信息是这样的
java.lang.OutOfMemoryError: Java heap space
出现堆溢出原因可能是大对象的分配,也可能是有内存泄漏。
针对堆溢出的原因,排查的方法主要有以下一些:
1)检查是否有大的对象分配,重点检查大的数组的分配,当然最好先通过jdk(比如jmap命令先获取dump)工具或者其他的内存分析工具(MAT等)先确定是那个类或哪些代码可能有问题。
2)检查JVM的参数设置是否会有Xmx设置过小的问题,有的话适当调大,合理的值要看机器本身的物理内存大小。
3)检查是否有大量的自定义的Finalizable对象,也有可能是框架内部提供的,考虑是否可以去除掉这些对象。

方法区(元空间)溢出

这个错误的信息是:java.lang.OutOfMemoryError: Metaspace
在HotSpot虚拟机中,使用元空间来实现方法区(1.8以后的版本),元空间中存放了虚拟机加载的类信息,常量,静态变量,JIT编译后的代码,元空间使用的是本地内存。
元空间溢出的原因可能是运行期间生成了大量的代理类,导致方法区撑爆,也可能是应用长时间运行没有重启。
解决的方法也有如下几条:
1)获取dump文件,通过过MAT工具查看是否由于反射而生成的代理类,如果有的话需要找到对应代码中的可能生成大量反射操作的地方。
2)检查JVM的参数设置中是否存在元空间设置过小的情况。
3)如果以上都没有找到的话尝试重启JVM(非必要不要用)。

栈溢出

这里说的栈指是本地方法栈,栈溢出的错误信息是:java.lang.OutOfMemoryError: unable to create new native Thread
出现这种错误一般都是线程数创建过多导致的。
解决的方法有如下:
1)通过jstack查找线程数是否有异常,如果有过多创建线程的现象,找到对应的代码修改
2)检查JVM的参数设置-Xss(每个线程的堆栈大小)设置的是否合理,如果过大需要调整
3)检查操作系统中系统空闲内存和操作系统本身限制是否设置合理,比如:/proc/sys/kernel/pid_max,/proc/sys/kernel/thread-max,maxuserprocess(ulimit -u),/proc/sys/vm/maxmapcount等等。

GC overhead limit exceeded

报错信息:java.lang.OutOfMemoryError: java.lang.OutOfMemoryError:
这个错误一般是堆设置太小导致的,当超过98%的时间用来做GC而回收的堆内存却不到2%的话会报这种异常。
解决的方法有:
1)获取dump文件,检查内存泄漏,如果没有的话,检查JVM堆内存的参数设置。
2)结合工具检查代码中的死循环和大内存分配部分的代码,优化这部分代码。

分配超大数组溢出

报错信息:java.lang.OutOfMemoryError: Request array size exceeds VM limit
这种错误的原因和解决方法都很明确了,就是不合理的超大数组分配导致的,要解决的话就是直接在代码中找到超大数组分配的地方修改掉。

交换溢出

报错信息:java.lang.OutOfMemoryError: Out of swap space
这种错误一般是操作系统导致的,可能是swap分区大小不够,也可能是其他进程占用过多内存导致。
解决的办法有:
1)加大swap分区大小,或者直接加大机器物理内存。
2)将占内存的进程尽可能的拆分出去。

本地方法溢出

报错信息:java.lang.OutOfMemoryError: stack_trace_with_native_method
这个是本地方法运行时发生的溢出,也就是所谓的JNI溢出,这种溢出比较难处理,需要有JNI调试和操作系统工具诊断能力,好在这种错误出现的概率极低。一旦出现,就需要很好的系统级别的分析和工具使用能力了,这就要靠自己慢慢修炼内功了。

3.1、堆溢出:Xmx:最大堆内存,Xms:最小堆内存,当Xmx=Xms时堆不扩展。-XX:+HeapDumpOnOutOfMemoryError ;实例化大量对象可测试堆溢出。
3.1.1、OOM解决:增大xmx扩大堆内存
3.2、栈溢出:栈溢出有俩种情况:
3.2.1、栈的深度超过最大深度限制,抛出StackOverflowError异常
3.2.2、栈扩展时内存不足,抛出OOM;
Xss:每个栈的大小;Xoss:本地方法栈大小,不过实际上xoss无效,栈容量只由-Xss参数设置。
3.2.3、实测中3.2.1说法有点不全。单线程下只有一个栈,所以只可能出现StackOverflowError,无论是栈的深度太大还是每个栈帧过大到账内存不足;多线程下会出现OOM,不断建线程时会出现内存不足;
3.2.4、OOM/StackOverflowError解决:
3.2.4.1、OOM:由于栈内存=操作系统内存 - 堆内存 - 方法区内存 - 程序计数器内存,所有可以减小堆内存来扩大栈内存大小。栈内存大小影响系统并发线程量(栈内存>=每个栈的大小xss线程量);具体设置由n台服务器,每台服务器m个cpu,则最大线程量=nm;每个栈的大小xss<=栈内存/n*m; 注意一下有个问题 ,这个公式没有直接内存?
3.2.4.2、StackOverflowError深度:如果使用jvm默认设置,栈的深度大多数情况下可达到1000~2000,足以在日常开发中使用。注意避免代码中存在超过1000的方法嵌套。每个方法嵌套对应一个栈帧。
3.2.4.3、StackOverflowError栈帧大小:单线程下避免代码中存在大量基本类型或对象引用。
3.2.4.4、多线程下假设每个栈帧特大,jvm是抛出OOM还是StackOverflowError?(待考察研究)
3.3、方法区OOM:-XX:PermSize:最小方法区内存大小;-XX:MaxPermSize:最大方法区内存大小。
3.3.1、OOM解决:避免大量的string.intern();避免大量的动态java(jsp,java反射)。
3.4、本机直接内存溢出:-XX:MaxDirectMemorySize:最大直接内存;默认为Xmx
3.4.1、OOM解决:使用NIO分配本机内存多注意是否超过MaxDirectMemorySize;平常开发容易忽略直接内存;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341