转载

JVM内存模型(运行时数据区)

每个线程私有,有几个线程就会有几个栈.栈也是一种数据结构,遵循FILO(先进后出),在线程创建执行方法时都会创建一个栈帧,进行压栈的操作.最先进行压栈的栈帧最后出来,最后压栈的栈帧最先出来.可以理解为栈是一个封住底的桶,而栈帧就是一个放入桶中,切面面积与桶相等的木块,你需要先取出后面放进去的木块,才能取出前面的.

JVM内存模型(运行时数据区)

栈帧中结构

在每个栈帧栈帧中都会存储几个常见的结构(我也不知道怎么讲) 如: 局部变量表,操作数栈,动态链接,方法出口(见图一).

  • [1] 局部变量表 : 存储同一方法内的局部变量,如(int a,String str)这里的a和str.局部变量中的对象句柄有指向堆内存具体对象位置的指针
  • [2] 操作数栈 : java文件会被编译为class字节码文件,字节码文件又会被翻译成机器码.操作数栈就是程序运行在执行JVM指令的时候,操作数的中转站(操作数栈也是一种栈结构).比如下例 int a = 1; int b = 2; int c = a+b;此时程序执行时会将1压入操作数栈,然后进行弹栈将1弹出来赋给a(第一行代码),然后将2压入栈,弹出2赋给b(第二行代码),将1和2压入栈(分两步进行),将1和2弹出栈,计算出结果3并赋值给c(第三行代码).
  • [3] 方法出口 : 记录着程序从什么时候进入这个方法,以便方法结束后,栈帧被弹出返回原程序执行位置.
  • [4] 动态链接 : 在程序运行期间将常量池中的符号替换为直接引用

程序计数器

每个线程私有,记录着程序运行期间,jvm指令执行的行数.

本地方法栈

用于执行本地方法的栈,每个线程私有.在java中有很多底层方法用native修饰,这些方法就是本地方法,本地方法是用其他语言写的比如c.

存放对象的位置.堆中分为年轻代和老年代.内存分配占比默认为1:2.在年轻代中分为Eden区,Survivor区(分为两部分,S0,S1),Eden:S0:S1:1:1.在对象新建之初对象会被放入Eden区,当这一区放满会触发Young GC,清理掉死亡对象,将剩余存活对象移入到S0区,S0区放满后依然会触发Young GC,并将剩余存活对象放入S1区,S1区满后依然会触发Young GC,并将剩余存活对象放回From区.

也就是说年轻代的三个分区在放满后都会触发,Young GC并移动剩余存活对象

JVM内存模型(运行时数据区)

Eden区剩余存存活对象移入Survivor区, 在Survivor区中,S0和S1的剩余存货对象都会移入到另一个区, 在对象每次进行移动操作时对象头中存储的迭代年龄会+1,当迭代年龄达到15,就会把对象移入到老年代.当老年代存满后会触发Full GC(Full GC会停止掉其他工作进程).

方法区

方法区也叫元空间,存放着常量池,静态变量,类的元信息等.堆中的对象会指向方法区中对应的类的信息.

原文  https://juejin.im/post/5d879b2c6fb9a06b2c32ccfb
正文到此结束
Loading...