Java 几种常见的OOM

本文介绍了Java虚拟机中几种常见的内存溢出异常及其解决方法,包括Java堆溢出、虚拟机栈和本地方法栈溢出、运行时常量池溢出及方法区溢出等,并提供了常用的JVM参数。

Java虚拟机内存有好几个运行时数据区会有OOM的异常,如果能够区分根据报错区分出是哪些区域报出来的异常,会更便于定位问题,解决问题。

1.Java堆溢出

原因:由于不断创建对象实例,当对象数量达到了最大堆的容量限制后产生内存溢出异常。

现象:java.lang.OutOfMemoryError: Java heap space

解决方法:

1)首先确认是内存泄露(Memory Leak)还是内存溢出(Memory Overflow);

2)如果是内存泄漏引起的,查看GC Roots引用链,找出为什么无法被垃圾回收的原因;

3)如果是内存溢出,检查虚拟机的堆参数(-Xmx最大值和-Xms最小值),对比物理内存看是否可以调大;

2.虚拟机栈和本地方法栈溢出

由于Hot Spot虚拟机的实现是不区分两者的,所以可以通过-Xss参数来设定栈容量。

java.lang.StackOverflowError:

原因:在单线程下,虚拟机栈容量太小或者定义了大量的本地变量,会抛出SO;

解决方法:增大虚拟机栈容量;

java.lang.OutOfMemoryError: unable to create new native thread

原因:在多线程下,大量创建新线程,会抛出OOM,每个线程的栈分配的内存越大,越容易产生;

解决方法:减少线程产生、降低最大堆、减少栈容量;

3.运行时常量池溢出

原因:代码在运行时创建了大量的常量,超出了常量池上限;

现象:java.lang.OutOfMemoryError: PermGen space

at java.lang.String.intern(Native Method)

解决方法:通过修改-XX:PermSize和-XX:MaxPermSize参数来修改方法区大小,从而修改常量池大小;

4.方法区溢出

原因:在运行时,ClassLoader动态加载了大量的Class信息,超出方法区上限;

现象:java.lang.OutOfMemoryError: PermGen space

at java.lang.ClassLoader.defineClass(Native Method)

解决方法:通过修改-XX:PermSize和-XX:MaxPermSize参数来修改方法区大小;

总之,引起OOM原因有很多,但是如果能够清楚了解底层内存存储的原理,就能够根据报错信息快速定位OOM报错原因,从而解决问题!

下面罗列一些经常用到的jvm参数:

所有用到的JVM启动参数:

-Xss2M       设置JVM栈内存大小

-Xms20M    设置堆内存初始值

-Xmx20M    设置堆内存最大值

-Xmn10M    设置堆内存中新生代大小

-XX:SurvivorRatio=8  设置堆内存中新生代Eden 和 Survivor 比例

-XX:PermSize=10M  设置方法区内存初始值

-XX:MaxPermSize=10M  设置方法区内存最大值

-XX:MaxDirectMemorySize=10M 设置堆内存中新生代大小

转载于:https://my.oschina.net/u/3633215/blog/1499863

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值