本章进入JVM学习的最后一节,此节主要分析的是堆,由于堆是JAVA程序中最经常使用使用到的地方,所以对这个地方有必要进行下细致的分析特别是OOM,言归正传,进入正文。java
1、内存溢出(OOM)的缘由session
在JVM中,有哪些内存区间?

堆溢出
public static void main(String args[]){ ArrayList<byte[]> list=new ArrayList<byte[]>(); for(int i=0;i<1024;i++){ list.add(new byte[1024*1024]); } }
永久区
生成大量的类 public static void main(String[] args) { for(int i=0;i<100000;i++){ CglibBean bean = new CglibBean("geym.jvm.ch3.perm.bean"+i,new HashMap()); } }
Java栈溢出
这里的栈溢出指,在建立线程的时候,须要为线程分配栈空间,这个栈空间是向操做系统请求的,若是操做系统没法给出足够的空间,就会抛出OOM

public static class SleepThread implements Runnable{ public void run(){ try { Thread.sleep(10000000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String args[]){ for(int i=0;i<1000;i++){ new Thread(new SleepThread(),"Thread"+i).start(); System.out.println("Thread"+i+" created"); } }
直接内存溢出
ByteBuffer.allocateDirect()没法从操做系统得到足够的空间

for(int i=0;i<1024;i++){ ByteBuffer.allocateDirect(1024*1024); System.out.println(i); System.gc(); }
2、MAT使用基础多线程
浅堆(Shallow Heap)与深堆(Retained Heap)
显示入引用(incoming)和出引用(outgoing)
支配树eclipse
nMemory Analyzer(MAT)
n基于Eclipse的软件
nhttp://www.eclipse.org/mat/

浅堆
一个对象结构所占用的内存大小

–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彻底一致。
3、使用Visual VM分析堆jvm
– java自带的多功能分析工具,能够用来分析堆Dump工具
类的柱状图 ,显示对象数量,总大小等:学习
从类试图切换到实例试图,显示全部的实例:spa
使用OQL查询:操作系统
返回引用了(0,0)这个点的全部对象线程
4、Tomcat OOM分析案例
Tomcat 在接收大量请求时发生OOM,获取堆Dump文件,进行分析。
若是是session过多引发OOM
– OOM因为保存session过多引发,能够考虑增长堆大小
– 若是应用容许,缩短session的过时时间,使得session能够及时过时,并回收
PS:具体的分析逻辑太长,此处不作详细介绍,能够参考附件。
感谢你们的学习,thank you ! 后面将进入多线程学习系列,敬请关注。
参考文献:
葛一鸣《深刻JVM内核》视频学习