jvm认识与探究(三)JMM内存模型

北城余情 提交于 2019-12-22 18:26:49

一、概述内存模型区域

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.方法区内存溢出
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!