你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

jvm内存模型和垃圾回收机制

2021/11/15 9:07:29

JVM内存模型

按线程来分,可分为两部分:一部分为线程独占的,一部分为线程共享的

线程共享:方法区(元空间), 堆

线程独占:程序计数器, 本地方法栈, 虚拟机栈

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ulVlQyn9-1636938035141)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20211104194926326.png)]

一个.java源文件通过javac命令,编译成.class字节码文件

java最重要的性质:跨平台性(一份代码,处处运行)

跨平台的原理:将编译过后得到的字节码文件放到不同的java虚拟机中去运行,然后JVM就会生成基于不同操作系统的二进制机器码

之所以 有对应不同平台的JDK就是因为如此,不同平台的JDK内部就包含着对应不同平台的JVM

在这里插入图片描述

在虚拟机栈中:只有程序中有线程开始运行,栈中就会给其分配一块内存空间 (这一块空间就叫线程栈)每个线程有一个私有的栈,随着线程的创建而创建

程序中每有一个线程开始运行,虚拟机栈就会开始给它分配一块内存空间

(村子里每搬来一户人家,村长就会给它家分配一个专属的房子 )

虚拟机栈

栈帧:

线程中每有一个方法,虚拟机栈就会给它分配一个栈帧,用来存放方法内的局部变量(a,b,c)等内容

局部变量表:

用来存放方法在执行过程中需要用到的局部变量(1,2,3)

操作数栈:

操作数在进行操作时,所处的内存空间,操作结束后就出栈给局部变量表中的局部变量保存

动态链接:

方法出口:

方法区

类信息,静态变量 和 **常量 **都放在方法区

本地方法区

本地方法

本地方法就是java调用非java代码的接口

当一个线程调用本地方法时,他就进入了一个全新的不再受虚拟机限制的世界,他和JVM有同样的权限。

本地方法可以访问JVM运行时数据区,可以直接使用程序计数器,可以直接从堆中分配任意数量的内存。

程序计数器

用来存放即将进行的那一行代码的行号地址,因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行

在堆中,分为

年轻代(1/3):Edon区(8/10),survivor区(S0(1/10),S1(1/10)),

老年代(2/3):Old区

minor gc:

在伊甸园区放满之后,JVM虚拟机会让字节码执行引擎开启一个垃圾收集线程

可达性分析算法:

先找出所有的GC Roots

已 GC Roots作为起点,从这些节点开始向下搜索引用的对象,将它们都标记为非垃圾,没被标记的都是垃圾.

然后将非垃圾都复制到survivor0区,剩余在Edon区的对象将被清理

minor gc 完成后,survivor区中的对象回到Edon区等待下次gc,下一次gc后,非垃圾对象将被放到s1区 ,然后就是每次gc非垃圾对象都会在survivor区来回跳,并且其分代年龄将会+1,当其分代年龄超过15后,将会被移动到Old区

GC Roots: 线程栈的本地变量,静态变量,本地方法栈等变量

JVM自带调优诊断工具 jvisualvm(图形化界面监控堆中数据变化)

企业常用Jvm调优工具Arthas

Full gc:

当老年代被装满了之后就会发生full gc,一旦发生full gc,将会对堆中所有的内存区域进行垃圾收集full gc收集完所有内存中的垃圾之后,如果还是没有多余空间来放新对象,那就回发生内存溢出OOM

Jvm调优的目的:

减少所有gc(核心:减少full gc)

原因:最终的主要目的是要减少STW,minor gc暂停时间较短,full gc暂停时间长,影响用户体验和系统性能

STW:(stop the world)

当堆中发生gc的时候,jvm底层会发生stop the world,此时用户线程将被停止一段时间

为何要设计STW???

如果没有stw,那在full gc的时候,当所有的根节点及其引用对象都别找出来了,然后可达性分析算法也把他们标记为非垃圾对象了.但是在这个过程中,用户的线程没有停止,一直运行,然后就啪嗒一下结束了.

可是gc线程此时还没有结束啊,而用户线程却一下就结束了.

然后在用户线程中内部的线程栈内存空间就被释放掉了,这也意味着线程内部的局部变量表等空间也会被释放,然后这些gc roots就嗝屁了,连带着那一整条对象引用链都嗝屁了.

一旦这些被释放掉的对象失去gc roots,(没人要了)他们就会变成垃圾对象,(在之前可达性分析已经标记过他们是非垃圾对象),此时,如果没有stw机制,提前暂停用户线程,一旦发生这种情况,那就只有重头再找非垃圾对象.这样程序将会很难结束.

在这里插入图片描述