一、概述内存模型区域
1.内存区域认识
a.内存模型区域分为两大块,一块是非堆区(
Metaspace
),一块是堆区(Heap
)
b.堆区分为两大块,一块是Old区
(老年代),一块是Young区
(年轻代)
c.Young区也区分为两大块,一块是Survivor区
(s0+s1),一块是Eden区
,Eden:s0:s1 = 8 :1:1,s0和s1一样大也可以叫做From和To
2.创建对象所在的区域
Java创建的对象存放于堆内存,一般情况下,新创建的对象都会分配到
Young区
中的Eden区
,一些特殊的、大的对象会直接分配到Old区
例如有对象A、B、C,已创建,存放于Eden区,但是内存空间都有大小限制,Eden区有80M,但是已经全部使用完,当再次新建对象时,就会对Eden存放的对象进行清理(即:垃圾回收,请看垃圾回收篇)。清理之后大部分对象不再存在,但是仍然会有部分对象存活,这时就会把存活对象分配到Survivor区(即:s0或s1)。
3.Survivor区详解
有上图可知,Survivor又分为s0和s1,又可以叫做From和To,同一时间节点s0和s1两个区域中只有一个区域会存在数据。
从上一点得知Eden区空间不足时会进行垃圾回收(Eden区的垃圾回收叫
Minor GC
),每Minor GC
一次会把Eden区的存活对象放进From区
,下一次Minor GC
又会把Eden区
和From区
的存活对象放入To区
,所以保证了s0或则s1其中一个区域一定有一个为空,并且每次Minor GC
后存活的对象的分代年龄+1,当存活对象的分代年龄到达阀值(官方设置15),则会进入Old区
,s0或则s1满了之后其中的所有对象也会进入Old区
.。
4.Old区
从上文可知
Old区
都是分代年龄较大的对象或则到达Survivor区
阀值的对象,并且当Old区
空间不足时也会进行垃圾回收,称作:Major GC
。
5.非堆区
非堆区在JDK1.8只有被称为元空间(即:Metaspace),可以理解为方法区的实现。用于存放类的各种信息,另外非堆区也包含了运行时数据常量池。
6.对象分配流程图理解
7.jvisualVm查看内存模型
执行命令打开jvisualVm工具
jvisualvm
安装插件:
https://visualvm.github.io/pluginscenters.html —>选择对应版本链接—>Tools—>Visual GC
验证查看图形化界面和描述一致
二、内存溢出
1.堆内存溢出
@GetMapping("/heap")
public String heap() throws InterruptedException {
while (true){
userList.add(new User());
Thread.sleep(1);
}
}
设置启动参数:-Xmx20M -Xms20M
稍等片刻即可看到oom,也可以用jvisualVm观察堆内存情况
2.方法区内存溢出
来源:CSDN
作者:七瑾年丶
链接:https://blog.csdn.net/qq_36994125/article/details/103653025