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、一般来说是某次升级之后才出现问题,可以直接分析定位本次升级代码,可能存在问题的地方