HotSpot和堆
- 堆
Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的
类加载器读取了类文件之后,一般会把什么放到堆中?
类,方法,常量,变量,保存我们所有引用类型的真实对象。 - 堆内存还要细分为三个区域
- 新生区(伊甸园区)
- 养老区
- 永久区
-
GC垃圾回收,主要是在伊甸园区和养老区
假设内存满了,OOM,堆内存不够,java.lang.OutOfMemoryError: java heap space
在jdk8之后,永久存储区改了个名字(元空间)。 -
新生区
类诞生,成长,甚至死亡的地方
- 伊甸园区 所有的对象都是在伊甸园区new出来的
- 幸存者区(0,1)
- 真理,经过研究,99%的对象就是临时对象。
- 永久区
这个区域常驻内存,用来存放JDK自身携带的Class对象,Interface元数据,存储的是java运行时的一些环境或者类信息,这个区域不存在垃圾回收,关闭JVM虚拟机会释放这个区域的内存。
一个启动类,加载了大量的第三方jar包,Tomcat部署了太多的应用,大量动态生成的反射类,不断地被加载,直到内存满,就会出现OOM
对象生命周期和GC
幸存区0–S0—from
幸存区1–S1—to
from区和to区,他们的位置和名分不是固定的(都只占新生代区的1/10),每次GC后会交换
也就是说:GC之后有交换,谁空谁是to
- 只要产生GC,伊甸园区必须全部清空
堆内存调优
- 默认情况下,分配的总内存,是电脑的1/4,而初始化的内存是1/16
- 在配置中修改参数语句:
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
使用Jprofiler工具分析OOM原因
- 在一个项目中,突然出现OOM故障,那么该如何排查错误?
- 能够看到代码第几行出错:内存快照分析工具,MAT,Jprofiler工具
- Dubug,一行行分析代码。
MAT,Jprofiler作用
- 分析Dump文件,快速定位内存泄漏
-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
-Xms 设置初始化内存分配大小
-Xmx 设置最大分配内存,默认1/4
-XX:+PrintGCDetails 打印GC垃圾回收信息
-XX:+HeapDumpOnOutOfMemoryError
- 获得堆中的数据
- 获得大的对象