zoukankan      html  css  js  c++  java
  • JVM分代模型

    重新回过头来看一些 JVM,思考一个问题:分出一个永久代我可以理解,为什么又要把堆分成新生代和老年代呢?私以为划分成新生代和老年代是因为它们里面对象的性质不同,要用不同的垃圾回收算法来回收效率才高,是为垃圾回收器服务才分出新生代和老年代的。

    本文说明新生代、老年代和永久代中对象的特性,以及何时它们何时触发 GC。

    JVM分代模型

    1
    2
    3
    4
    5
    
    堆的大小可以用这几个参数来设置:
    
    1. “-XX:InitialHeapSize”和“-XX:MaxHeapSize” 就是初始堆大小和最大堆大小
    2. “-XX:NewSize”和“-XX:MaxNewSize” 是初始新生代大小和最大新生代大小
    3. “-XX:PretenureSizeThreshold=10485760” 指定了大对象阈值是10MB。
    

    新生代

    大部分对象存活的周期很短,就会放在新生代中。ParNew垃圾收集器会使用复制算法,回收新生代中的对象。复制算法中会将新生代分成 Eden 区和两个 Survivor 区,当 Eden 区满的时候就会触发垃圾回收算法。

    老年代

    少部分对象存活周期比较长,或者因为一些特殊原因会进入到老年代。那么什么样的情况下,对象会进入老年代呢?

    1. 一个实例对象在新生代中,成功躲过 15 次垃圾,就说明他已经15岁了。成为老人的它就能进入到老年代了。

      具体几岁算是一个老人可以通过 -XX:MaxTenuringThreshold 参数进行设置。

    2. 动态年龄判断,当前放对象的 Survivor 区域里,一批对象的总大小大于了这块 Survivor区域内存大小的50%,那么此时大于等于这批对象年龄的对象,就可以直接进入老年代。

    3. 大对象直接进入老年代,可以通过 -XX:PretenureSizeThreshold 参数进行设置

    4. Minor GC 之后发现剩余对象太多,无法放到另一个 Survivor 区,这些对象会直接进入老年代

    老年代什么时候会触发 Old GC 呢?其实总结起来有 2 种情况:

    1. 老年代未开启分配担保,老年代对象大小小于新生代中对象大小;老年代开启分配担保,但是老年代对象大小小于历次 Minor GC 之后进入老年代对象的大小。以上情况会进行 Old GC。
    2. 经过 Minor GC 之前的检查,正式进行 Minor GC 后,Survivor 放不下剩余对象,老年代也放不下剩余对象,就会进行 Old GC。

    如果 Old GC 之后老年代还是放不下剩余对象,就会 OOM。

    具体关于老年代未开启分配机制,以及触发 Minor GC 和 Old GC 流程的内容,可以看《图解GC的过程

    永久代

    JVM 里的永久代其实就是方法区,可以认为永久代就是放一些类信息的。

    永久代一般不会发生 GC,具体情况还不是很清楚,以后会补充。

  • 相关阅读:
    linux创建用户
    使用Myeclipse插件将wsdl生成java客户端代码
    JAVA时间格式转换大全
    数据库DDL语句书写规范
    jacon
    应用jacob组件造成的内存溢出解决方案(java.lang.OutOfMemoryError: Java heap space)
    为什么使用内部类
    HBase查找一条数据的过程
    Hadoop:输入,输出,key,value格式
    ArrayList和Vector的区别
  • 原文地址:https://www.cnblogs.com/shuiyj/p/13185105.html
Copyright © 2011-2022 走看看