标题

  • jdk体系结构
  • jvm虚拟机
  • 栈帧
  • 局部变量表、操作数栈
  • 方法出口
  • 程序计数器
  • 方法区
  • 本地方法栈(现在基本不用)
  • jvm调优实战


jdk体系结构

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_jvm

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_局部变量_02

jvm虚拟机

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_本地方法_03


紫色区域是线程独享

橘色区域是所有线程共享

栈帧

虚拟机栈(线程栈):存放局部变量。

例如:下图中a、b、c、math、

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_执行引擎_04


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

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_jvm_05


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

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_执行引擎_06

局部变量表、操作数栈

当方法执行完毕后释放栈帧内存区域。

先进后出,先执行main()方法在,再执行compute()方法。然后销毁compute(),再进入main()

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_执行引擎_07

方法出口

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_局部变量_08

程序计数器

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_jvm_09


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

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_jvm_10

方法区

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

方法区里面存放

常量

静态变量

类信息(字节相关的类信息)

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_本地方法_11


虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_jvm_12

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

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

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_执行引擎_13


new出来的对象最先放在eden区的。

eden区的大小是固定的。 当eden区放满时,jvm会进行==minor gc(young gc)==执行引擎会开启一个垃圾收集线程,来收集eden区的垃圾对象。

那什么叫垃圾对象的,可用如下算法可达性分析算法(如图)

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_本地方法_14


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

没有被处理的对象的分代年龄会加一

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_执行引擎_15


一个对象包含对象头,里面有一个分代年龄(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次还被引用),这种对象会被放到老年代。

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_jvm_16

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

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

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

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

jvm调优实战

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_jvm_17


虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_执行引擎_18


虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_局部变量_19


虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_本地方法_20


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

虚拟机部署jar包并用nginx做负载均衡 java虚拟机底层_本地方法_21