怎么判断对象是否需要回收?

  • 引用计数法:给对象添加一个引用计数器,每有一个地方引用它就+1,引用失效就-1,如果是0则回收。
    • 优点:效率高;缺点:无法回收循环引用的对象
  • 可达性分析法:当一个对象到GC Roots对象没有任何引用链,则回收
    • GC Roots对象包括虚拟机栈帧中引用的对象、方法区静态变量/常量引用的对象、Native方法引用的对象
    • 第3章 垃圾回收 - 图1

那么如何判断对象是否被引用呢?

  • 强引用:类似**Object obj = new Object()** ,只要强引用存在,就不会回收掉
  • 软引用:用SoftReference来实现,用来描述还有用但非必需的对象,会在内存溢出之前回收
  • 弱引用:用WeakReference来实现,用来描述非必需的对象,不管内存够不够在下一次垃圾回收时一定会被回收
  • **虚引用:用PhantomReference来实现,虚引用的对象无法获得实例,随时都可能回收

垃圾回收算法?

  • 标记-清除法:标记所有要回收的对象,然后回收
    • 缺点:效率不高且会产生大量不连续的内存碎片,导致分配大对象时频繁GC
    • 第3章 垃圾回收 - 图2
  • 复制算法:**一般用于新生代,**将内存分成两块,每次只使用一块,每次回收都复制到另一块上,清除原来的空间
    • 缺点:内存缩小一半,浪费
    • 第3章 垃圾回收 - 图3
  • 标记整理法:一般用于老年代,和标记清除法一样,但是在标记后先整理,然后再回收
    • 第3章 垃圾回收 - 图4

如何真正实现垃圾回收?

第3章 垃圾回收 - 图5

具体介绍一下CMS?

  • CMS基于标记-清除法,目标为获取最短回收停顿时间的收集器第3章 垃圾回收 - 图6
  • 共分为四个步骤:
    • 初始标记:只标记一下GC Roots能连接的对象
    • 并发标记:GC Roots tracing,即可达性分析
    • 重新标记:修正并发标记期间因用户线程导致产生变动的对象的标记
    • 并发清理:并发垃圾回收
  • CMS优点:不停顿,并发执行。
  • 缺点:并发执行对CPU资源压力大,且无法处理在处理过程中产生的垃圾,且标记清除法会产生垃圾碎片

**

具体介绍一下G1?

  • G1是当前垃圾收集器最前沿成果之一,采用标记整理法,且能精确控制停顿时间
  • 第3章 垃圾回收 - 图7
    • 和CMS很类似,但是G1会把内存分成多个独立的区域,并根据允许回收的时间优先回收垃圾最多的区域

具体说一下新生代和老年代的对象

  • 首先大多数情况,对象在新生代Eden区中分配。当Eden区空间不够时,会触发一次Minor GC(新生代GC)
  • 大对象直接进入到老年代
  • 长期存活的对象直接进入老年代。
    • 对象在Eden区出生并经过一次Minor GC仍然存活且能被Survivor区容纳,会被移动到Survivor区,并且设置年龄为1岁。每熬过一次Minor GC年龄就+1
    • 如果Survivor区中相同年龄的所有对象大小总和大于Survivor区的一半,那么年龄大于等于该年龄的对象都去老年代