JVM学习十三:JVM之堆分析
本章进入JVM学习的最后一节,此节主要分析的是堆,因为堆是JAVA程序中最常用使用到的地方,因此对这个地方有必要进行下细致的分析特别是OOM,言归正传,进入正文。
一、内存溢出(OOM)的原因
在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(); }
二、MAT使用基础
浅堆(Shallow Heap)与深堆(Retained Heap)
显示入引用(incoming)和出引用(outgoing)
支配树
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完全一致。
三、使用Visual VM分析堆
– java自带的多功能分析工具,可以用来分析堆Dump
类的柱状图 ,显示对象数量,总大小等:
从类试图切换到实例试图,显示所有的实例:
使用OQL查询:
返回引用了(0,0)这个点的所有对象
四、Tomcat OOM分析案例
Tomcat 在接收大量请求时发生OOM,获取堆Dump文件,进行分析。
如果是session过多引起OOM
– OOM由于保存session过多引起,可以考虑增加堆大小
– 如果应用允许,缩短session的过期时间,使得session可以及时过期,并回收
PS:具体的分析逻辑太长,此处不做详细介绍,可以参考附件。
感谢大家的学习,thank you ! 后面将进入多线程学习系列,敬请关注。
参考文献:
葛一鸣《深入JVM内核》视频学习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2016-06-21 JSP 学习一