Java 出现内存溢出的定位以及解决方式

在上一节中Java虚拟机内存分布   说了Java虚拟机中分为五个区域,并且也知道了在Java程序计数器区域不会出现OOM(OutOfMemeryError),那么下面就对除了程序计数器以外的四个区域出现OOM的原理以及解决方式进行讲解。


1.Java虚拟机栈与本地方法栈

栈的大小控制参数时 -Xss。

Java虚拟机在栈中定义了两种异常,StrackOverFlowError和OutOfMemeryError。当请求栈的深度大于java虚拟机所允许的最大深度则抛出StrackOverFlowError;如果Java虚拟机在栈扩展时,没有申请到足够的空间时,则抛出OutOfMemeryError。

StrackOverFlowError:Java虚拟机在运行中,调用方法时,都要创建栈帧,当栈的空间不够时就会产生StrackOverFlowError。那么对应的解决方法就只能是调节-Xss参数,或者减少方法的调用,减小栈帧的大小两种方式。

OutOfMemeryError:在栈上出现OOM一般是多线程的情形。首先咋们解析一下栈使用的空间可以有多大,拿32位操作系统来举例, 最大内存2G - Xmx(最大堆容量)- MaxPermSize(最大方法区容量)- 虚拟机本身耗费的内存和程序计数器使用的内存。 剩下的内存就是栈可以使用的空间,当Xss配置的参数一定时,那么在不断的创建线程过程中,遇到不能申请到栈空间的时候就会抛出OOM,那么对应的解决方式就是,调节-Xss参数降低栈大小,或者调节-Xmx以及MaxPermSize的大小扩大留给栈的空间。


2.方法区内存溢出

方法区的大小通过-PermSize和-MaxPermSize控制。

因为类常量和运行时常量也存储在方法区中,所以运行时常量过多也可导致方法区的OOM,但是没有直接控制常量池大小的参数,只能通过-PermSize和-MaxPermSize来间接控制。

在Spring以及Hibernate,Mybatis中都会使用GeneratedConstructorAccessor、动态代理以及CGLib字节码增强技术的等动态生成类,那么就需要强大的方法区来支撑。


3.堆内存的溢出

堆内存的溢出比较复杂,需要调节GC等多种参数,我们在后面的章节中会进行讲解。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值