JVM学习十三:JVM之堆分析

本章进入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内核》视频学习

相关文章
相关标签/搜索