本文共 1052 字,大约阅读时间需要 3 分钟。
内存溢出(OOM)的原因
在JVM中,有哪些内存区间?
1、堆:堆溢出
2、永久区溢出(perm)
3、线程栈:java栈溢出
在创建线程的时候,需要为线程分配栈空间,这个栈空间是向操作系统请求的,如果操作系统无法给出足够的空间,就会抛出OOM。
4、直接内存:直接内存溢出
- ByteBuffer.allocateDirect()无法从操作系统获得足够的空间
MAT使用
基于Eclipse的软甲,官网下载地址( ),需要下载和JDK位数相同的。
在下图中,C是H的直接支配对象。当支配者被回收,被支配对象也被回收。
浅堆
- 一个对象结构所占用的内存大小
-
- 3个int类型以及一个引用类型合计占用内存3*4 + 4=16个字节。再加上对象头的8个字节,因此String对象占用的空间,即浅堆的大小是16+8=24字节。
- 对象大小按照8字节对齐
- 浅堆大小和对象内容无关,只和对象结构有关。
深堆
- 一个对象被GC回收后,可以真实释放的内存大小。
- 只能通过对象访问到的(直接或者间接)所有对象的浅堆之和(支配树) 示例: 上图可以看到,所有的Point实例浅堆和深堆的大小都是16字节。而dLine对象,浅堆为16字节,深堆也是16字节,这是因为dLine对象内的两个点f和g没有被设置为null,因此,即使dLine被回收,f和g也不会被释放。对象cLine内的引用对象d和e由于仅在cLine内还存在引用,因此只要cLine被释放,d和e必然也作为垃圾被回收,即d和e在cLine的保留集内,因此cLine的深堆为16*2+16=48字节。
对于aLine和bLine对象,由于两者均持有对方的一个点,因此,当aLine被回收时,公共点a在bLine中依然有引用存在,故不会被回收,点a不在aLine对象的保留集中,因此aLine的深堆大小为16+16=32字节。对象bLine与aLine完全一致。
使用Visual VM分析堆
从类试图切换到实例试图,显示所有的实例。
Tomcat OOM分析案例
1、Tomcat OOM
- Tomcat在接收大量请求时发生OOM,获取Dump文件,进行分析。
- 使用MAT打开堆。
- 分析目的: 1)找出OOM的原因 2)推测系统OOM时的状态 3)给出解决这个OOM的方法 OQL使用查询类情况。 解决方法:
- 1、OOM由于保存session过多引起,可以考虑增加堆大小。
- 2、如果应用允许,缩短session的过期时间,使得session可以及时过期,并回收。
转载地址:http://lnfoi.baihongyu.com/