01-JDK1.8内存模型

01-JDK1.8内存模型
  • jvm内存模型
    • 线程隔离数据区
    • 线程共享的数据区
  • JVM对象栈区
  • 内存分配策略
  • GC垃圾收集

jvm内存模型

线程隔离数据区

程序计数器(Program Counter Register):

一小块内存空间,单前线程所执行的字节码行号指示器。字节码解释器工作时,通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。。

虚拟机栈

虚拟机栈的生命周期是和线程相同的,是在JVM运行创建的,在线程方法执行的过程中会创建一个栈帧。主要用于存放局部变量表、操作栈、动态链接、方法出口等信息。

本地方法栈

本地方法栈则是为执行本地方法(Native Method)服务的。

线程共享的数据区

方法区(Method Area):

用于存储JVM加载的类信息、常量、静态变量、即使编译器编译后的代码等数据。

运行时常量池(Runtime Constant Pool):

是方法区的一部分,用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法取得运行时常量池中。具备动态性,用的比较多的就是String类的intern()方法。

堆:

存放所有对象实例的地方。

注意:JDK1.8,方法区已经移动到了元空间,元空间并不存在于JVM虚拟机内存,而是使用本机的本地内存。

JVM对象栈区

JVM栈用于存放对象示例。

  • 新生代中Eden与两个survivor区的比例时8:2。
  • 新生代与老年代的比例为1:2

内存分配策略

  • 1 对象优先在 Eden 分配

大多数情况下,对象在新生代 Eden 区分配,当 Eden 区空间不够时,发起 Minor GC。

  • 2 大对象直接进入老年代

大对象的出现会提前触发GC以获取足够的连续空间。当对象大小大于eden区的时候会直接扔到old区。

-XX:PretenureSizeThreshold,大于此值的对象直接在老年代分配,避免在 Eden 区和 Survivor 区之间的大量内存复制。(PretenureSizeThreshold默认值是0,意味着任何对象都会现在新生代分配内存)

  • 3 长期存活的对象进入老年代

为对象定义年龄计数器,对象在 Eden 出生并经过 Minor GC 依然存活,将移动到 Survivor 中,年龄就增加 1 岁,增加到一定年龄则移动到老年代中。(默认是15)

-XX:MaxTenuringThreshold 用来定义年龄的阈值。

  • 4 动态对象年龄进入老年代。

当 Survivor空间中相同年龄所有对象的大小总和大于 Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,而不需要达到默认的分代年龄。

  • 5 空间分配担保

简单通俗易懂:当触发MinorGC时,存活的对象会转移到另外一个Survivor区,当这个区域无法保存还存活的对象,那么就会触发分配担保机制。直接将对象复制到老年代中。

原理:在发生MinorGC之前,虚拟机先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果条件成立的话,那么 Minor GC可以确认是安全的。如果不成立的话虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。

如果允许那么就会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小。如果大于,将尝试着进行一次 Minor GC。如果小于或者HandlePromotionFailure设置不允许冒险,那么就要进行一次 Full GC(担保失败)。

GC垃圾收集

当Eden区没有空间进行分配时,将进行一次Minor GC

Minor GC

Eden区域满了,或者新创建的对象大小 > Eden所剩空间

复制算法不会产生内存碎片。所以年轻代的GC是使用复制算法的在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置,默认15)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。

两个survivor只有一个会有对象,另外一个用于对象复制。也就是复制算法。

Full GC

清理整个堆空间—包括年轻代和老年代。触发条件:

  • (1)调用Sytem.GC()
  • (2)老年代空间不足时
  • (3)空间分配担保失败

Major GC

清理老年代。

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部