java GC

 

资料: 

  GC Roots、分代(R大):https://www.zhihu.com/question/53613423

 

0. 引用分类

  1. 强引用

  2. 软引用

  3. 弱引用

  4. 虚引用

 

1. GC Roots

   1. 虚拟机栈(栈帧中本地变量表)中的引用

  2. 本地方法栈 JNI (Native 方法) 的引用

  3. 方法区中类静态属性的引用

  4. 方法区中常量的引用

 

  引用:*obj 在栈中,保存obj对象的地址

   对象:object 在堆中

 

2. 可达性分析

  标记活着的对象

  通过GC Roots作为起点,向下搜索引用链。当一个对象到 GC Roots 没有引用链相连时,说明可回收。

 

  实现:枚举根节点

  1. stop the world

    保证引用不会变化,CMS在枚举根节点时也会停顿

  

3. 回收对象(谁会被GC)

  从root搜索不到,而且经过第一次标记、清理后(finalize方法),仍然没有复活的对象。

 

  标记分为两步:

    1. 是否需要调用finalize方法

    2. 调用finalize方法之后是否存活

 

4. GC 触发条件(什么时候GC)

  Minor GC / young GC:

    1. eden区满

  

  Old GC:

    1. CMS定期检查Old Gen使用量,超过了触发比例启动CMS GC,对Old Gen做并发收集。

 

  Full GC:

    1. 升到老年代的对象大于老年代剩余空间full gc

    2. 有Perm Gen的话,要在Perm Gen分配空间但是没有足够空间

 

 5. 分代的好处

  1. 对串行:若无分代,一次GC整个堆(对传统的serial来说),stop the world 停顿时间太长,不如一次只收集一部分,减少停顿时间,young gen需要收集的次数多,old gen需要次数少。

  // 未理解:2. 对并行:提升GC能够应付的应用内存分配速率

 

 

6. 谁会进入老年代

  1. 大对象直接进入老年代(高于阈值)

  2. 长期存活的对象进入老年代

    熬过15次Minor GC

  3. 动态对象年龄判定

    Survivor中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于等于该年龄的对象直接进入老年代

  4. 老年代分配担保

    Minor GC后大量对象存活,Survivor无法容纳的对象进入老年代

 

7. 方法区回收

  对象:废弃常量、无用的类

 

  1. 废弃常量

    常量池中的 字面量、类、方法、字段的符号引用

    例:"abc"在常量池中,但没有任何一个String对象是"abc",也没有其他地方引用了这个字面量。

 

  2. 无用的类 (可能被回收)

    1. 该类所有实例被回收

    2. 加载该类的ClassLoader被回收

    3. 该类Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类方法

 

  3. 元空间的垃圾回收

    资料:https://www.cnblogs.com/duanxz/p/3520829.html

    1. 在元空间中,类和其元数据的生命周期和其对应的类加载器是相同的。

    2. 每一个类加载器的存储区域都称作一个元空间,所有的元空间合在一起就是我们一直说的元空间。当一个类加载器被垃圾回收器标记为不再存活,其对应的元空间会被回收。

    3. 元空间虚拟机负责元空间的分配,其采用的形式为组块分配。组块的大小因类加载器的类型而异。在元空间虚拟机中存在一个全局的空闲组块列表。当一个类加载器需要组块时,它就会从这个全局的组块列表中获取并维持一个自己的组块列表。当一个类加载器不再存活,那么其持有的组块将会被释放,并返回给全局组块列表。类加载器持有的组块又会被分成多个块,每一个块存储一个单元的元信息。组块中的块是线性分配(指针碰撞分配形式)。组块分配自内存映射区域。这些全局的虚拟内存映射区域以链表形式连接,一旦某个虚拟内存映射区域清空,这部分内存就会返回给操作系统。

 

8. 复制算法

  资料:

    R大讲复制算法

posted @ 2020-09-23 14:59  Numerz  阅读(102)  评论(0编辑  收藏  举报