内存溢出问题的分析与解决【JVM初体验】
这是关于Java虚拟机的第一篇总结,开篇首先介绍一下 jdk , jre , jvm的关系吧。
jdk jre jvm 之间的关系
jdk java开发工具包 (包含jre)jre java运行环境 (包含 JavaSeAPI + jvm)
jvm java虚拟机 (在jdk中通过javac编译生成的字节码文件 加载到jre中运行 也就是加载到道jvm中运行)
官方文档给的结构图:
接下来 首先写一个测试程序:
package cn.zj.jvm; import java.util.ArrayList; import java.util.List; public class firstjvm { public static void main(String[] args) { List<Demo> demoList=new ArrayList<Demo>(); while(true) { demoList.add(new Demo()); } } }
通过分析发现,最终会报错:
我们可见 ,该错误是由于堆内存溢出造成的。
试想一下,当我们有成千上万行代码,报错时,
我们怎么定位错误呢?
很显然,我们无法直接定位,这时候需要借用工具帮助。
Step1 : 我们首先需要建立一个堆内存快照.
通过jvm参数:
-XX:+HeapDumpOnOutOfMemoryError (建立堆快照)
-Xms20m -Xmx20m(限制内存为25m)
输入参数:
运行之后:
项目文档中生成的快照:
Step2:下载分析工具(Memroy Analyzer MAT)
Step3:通过分析工具得出结果
打开快照:
参数说明:
Shallow Heap 表示当前对象本身所占用的内存大小,不包含引用对象
Retained Heap 表示当前对象本身所占用的内存大小以及当前直接或间接所引用的对象总和(如果要进行垃圾回收,可释放的内存)
最终得出结论是Demo对象所占百分比过高,导致内存溢出。
关于jvm入门的第一个例子到此结束了!