30_堆内存溢出
约 535 字大约 2 分钟
2024-08-10
堆内存如何溢出的
1、一开始,对象在
Eden区分配,Eden区满了之后触发Young GC,存活对象进入S区2、高并发场景下,
Young GC后存活对象太多,存活对象直接进入老年代3、加入有一批存活对象要进入老年代,老年代
CMS GC后还是放不下,此时就触发堆内存溢出了
发生堆内存溢出原因一句话总结:有限的内存中放了过多的对象,并且 GC 过后大部分对象都存活,无法继续放入对象,引发内存溢出
发生堆内存溢出的主要场景:
1、系统承载高并发请求,导致大量对象是存活的,无法继续放入新对象,引发
OOM系统崩溃2、系统存在内存泄漏,很多对象都是存活的,触发
GC无法回收,最后内存溢出
模拟堆内存溢出
JVM 参数中设置堆内存大小 -Xms10m -Xmx10m,这里设置为 10MB
我们在 while 循环里不停的创建对象,并且对象都是放在 List 中被引用的,也就是无法被回收
Eden 区满了之后全部存活对象转移到老年代,反复多次之后老年代满了
Eden 区再次满了,进行 Full GC,但是回收不了任何对象,内存溢出
/**
* @ClassName HeapMemoryDemo
* @Desciption 堆内存溢出 Demo
* @Author MaRui
* @Date 2024/2/22 17:41
* @Version 1.0
*/
public class HeapMemoryDemo {
public static void main(String[] args) {
long count = 0;
List<Object> list = new ArrayList<Object>();
while (true) {
list.add(new Object());
System.out.println("目前创建第 " + (++count) + " 个对象");
}
}
}执行代码后我们可以在控制台中看到打印日志信息,Java heap space 很明显是堆内存 OutOfMemoryError
目前创建第 358230 个对象
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space堆内存溢出解决
1、分析内存快照,找到是什么类占据了内存
2、一般来说是某次升级之后才出现问题,可以直接分析定位本次升级代码,可能存在问题的地方