Java虚拟机JVM底层原理分析

jdk体系结构

jvm虚拟机


紫色区域是线程独享
橘色区域是所有线程共享

栈帧

虚拟机栈(线程栈):存放局部变量。
例如:下图中a、b、c、math、

每个线程在运行前,java虚拟机都会为其分配一块自己独立的栈内存空间。存放局部变量。

栈帧是栈中更细致的内部结构,线程中每个方法分配一个栈帧(专属独立)。如下图

局部变量表、操作数栈

当方法执行完毕后释放栈帧内存区域。
先进后出,先执行main()方法在,再执行compute()方法。然后销毁compute(),再进入main()

方法出口

程序计数器


每个线程分配一个程序计数器 ,记录当先线程执行代码的行号。字节码执行引擎动态修改它

方法区

jdk1.8 以后叫做 元空间
实际上是直接放内存里的。
严格意义不算jvm中的

方法区里面存放
常量
静态变量
类信息(字节相关的类信息)


本地方法栈(现在基本不用)

private native void start0()
java与c交互,就是使用本地方法
执行到这行代码 时,会由底层的执行引擎去分析这个本地方法,去调用c语言的库函数(Windows 中的.dll文件)。
这里面的实现使用c语言实现的。


new出来的对象最先放在eden区的。
eden区的大小是固定的。 当eden区放满时,jvm会进行==minor gc(young gc)==执行引擎会开启一个垃圾收集线程,来收集eden区的垃圾对象。
那什么叫垃圾对象的,可用如下算法

可达性分析算法(如图)

所有在gc route链条上的对象都是非垃圾对象。把非垃圾对象直接复制(复制算法)到survivor区的一块空的区去。eden区剩余对象即垃圾对象(没有gc router指向的对象)直接清理掉。
没有被处理的对象的分代年龄会加一

一个对象包含对象头,里面有一个分代年龄(gc的次数)
等待eden区再次满了,再次触发minor gc,会回收 eden区和survivor区中from区的对象,gc router链条上的对象会直接复制到survivor区的to区中,eden区和survivor区中from区的垃圾对象直接销毁。

等待eden区再次满了,再次触发minor gc,会回收 eden区和survivor区中to区的对象,gc router链条上的对象会直接复制到survivor区的from区中,eden区和survivor区中to区的垃圾对象直接销毁。

以此类推…

当分代年龄达到15(gc15次还被引用),这种对象会被放到老年代。

当老年代放满了会触发full gc
full gc会回收整个堆
如果没办法回收 就会发生OOM(内存溢出)

web应用中可能会被移动到老年代的对象
线程池、静态变量引用的对象、spring容器中的been、service、controller、代码初始化的缓存对象

STW(stop the world)
执行引擎开启 gc 线程时候STW(停掉用户线程),专心收集垃圾。

jvm调优的目的:减少STW的时间(减少full gc 次数,和一次full gc的时间)

jvm调优实战





面试题:能否对jvm调优,让其几乎不发生full gc

解答

发布了57 篇原创文章 · 获赞 5 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章