JavaJVM · Java虚拟机原理 · JVM上语言·框架· 生态系统

面试笔记-GC回收机制

2020-04-11  本文已影响0人  Android学习之旅

不写废话,帮助你快速理解应对面试

目录

垃圾的定义
可达性分析
GC Root对象
回收的时机
如何进行垃圾回收

  1. 标记清除算法(Mark and Sweep GC)
  2. 复制算法(Copying)
  3. 标记整理算法(Mark-Compact)

JVM分代回收策略

  1. 新生代
  2. 老年代
    JVM的引用关系

垃圾的定义

内存中没有用的对象。
怎么判断是否有用呢?——可达性分析

可达性分析

可达性分析算法(Reachability Analysis)的基本思路是,通过一些被称为引用链(GC Roots)的对象作为起点,从这些节点开始向下搜索,搜索走过的路径被称为(Reference Chain),当一个对象到 GC Roots 没有任何引用链相连时(即从 GC Roots 节点到该节点不可达),则证明该对象是不可用的。

GC Root对象

关于内存的区域分布,可以参考:面试笔记-Java内存分配

在Java中,有以下几种对象可以作为GCRoot:

  1. Java虚拟机栈(局部变量表)中的引用的对象。
  2. 方法区中静态引用指向的对象。
  3. 仍处于存活状态中的线程对象。
  4. Native方法中 JNI 引用的对象。

回收的时机

  1. AllocationFailure:在堆内存中分配时,如果因为可用剩余空间不足导致对象内存分配失败,这时系统会触发一次GC。
  2. System.gc():在应用层,可以主动调用此API来进行垃圾回收

如何进行垃圾回收

标记清除算法(Mark and Sweep GC)

标记清除算法
标记清除算法(Mark-Sweep)是最基础的一种垃圾回收算法,它分为2部分,先把内存区域中的这些对象进行标记,哪些属于可回收标记出来,然后把这些垃圾拎出来清理掉。清理掉的垃圾就变成未使用的内存区域,等待被再次使用。
缺点:会产生碎片。

复制算法(Copying)

复制算法(Copying)是在标记清除算法上演化而来,解决标记清除算法的内存碎片问题。
它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。
当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。保证了内存的连续可用,内存分配时也就不用考虑内存碎片等复杂情况,逻辑清晰,运行高效。

复制算法
优点:按顺序分配内存即可,实现简单、运行高效,不用考虑内存碎片。
缺点:可用的内存大小缩小为原来的一半,对象存活率高时会频繁进行复制。

标记整理算法(Mark-Compact)

标记整理算法(Mark-Compact)标记过程仍然与标记 --- 清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,再清理掉端边界以外的内存区域。


标记整理算法

优点:这种方法既避免了碎片的产生,又不需要两块相同的内存空间,因此,其性价比比较高。
缺点:仍需要进行局部对象移动,所以一定程度上还是降低了效率。

JVM分代回收策略

分代回收的中心思想就是:对于新创建的对象会在新生代中分配内存,此区域的对象生命周期一般较短。如果经过多次回收仍然存活下来,则将它们转移到老年代中。


JVM分代回收

新生代

  1. Eden区满的时候会进行垃圾回收,将 Eden 区的垃圾对象回收清除,并将存活的对象复制到 From Survivor 区域,此时To Survivor是空的。
  2. 下一次 Eden 区满时,再执行一次垃圾回收。此次会将 Eden和From Survivor 区中所有垃圾对象清除,并将存活对象复制到To Survivor,此时From变为空。
  3. 如此反复在From和 To之间切换几次(默认 15 次)之后,如果还有存活对象。说明这些对象的生命周期较长,则将它们转移到老年代中。

老年代

一个对象如果在新生代存活了足够长的时间而没有被清理掉,则会被复制到老年代。
老年代的内存能存放更多的对象。如果对象比较大(比如长字符串或者大数组),并且新生代的剩余空间不足,则这个大对象会直接被分配到老年代上。

JVM的引用关系

引用 GC回收时间 使用实例
强引用 GC不会回收 Object obj = new Object();
软引用 内存不足,将其回收 SoftReference<Object> sobj = new SoftReference();
弱引用 第一次GC,遍历到有弱引用,回收 WeakReference<Object> sobj = new WeakReference();
虚引用 完全不对生存时间构成影响,无法通过虚引用获取一个对象的实例 不会使用
上一篇 下一篇

猜你喜欢

热点阅读