堆内存模型设计是为了提高垃圾回收的效率,那么如何判断一个对象是垃圾?
如何判断一个对象是垃圾 引用计数法如果要操作对象,必须通过引用来进行。如果一个对象没有任何引用与之关联,则说明 该对象基本不太可能在其他地方被使用到。那么这个对象就成为可被回收的对象了。这种方 式实现简单,效率较高,但是它无法解决循环引用的问题,因此在 Java 中并没有采用这种 方式(Python 采用的是引用计数法)。
以一个 GC Root 对象作为起点进行搜索,如果在 GC Roots 和对象之间没有可达路径, 则称该对象是不可达的。
栈帧中的本地变量表中引用的对象。
方法区中静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中引用的对象。
效率较低,有空间碎片。Old 区使用的算法
空间碎片少,但会浪费空间。存活对象较少才会使用的算法。young 区使用的算法。
只有一个垃圾回收线程,在垃圾回收时暂停用户代码线程,如 Serial 和 Serial Old 收集器。
吞吐量优先,多个垃圾收集器线程共同工作, 尽快完成垃圾收集。如 ParNew, Parallel Scanvenge, Parallel Old 收集器。
停顿时间优先,用户线程和垃圾回收线程一同工作,用户代码线程也会完全停止一 小段时间,如 CMS,G1 收集器。
CMS(concurrent mark sweep,并发标记扫描)收集器是并发收集器,是基于标记 ——清理的算法进行垃圾回收,用于 OldGC
优点:并发收集、低停顿
缺点:会产生大量空间碎片,停顿时间虽然短但是不可控。
G1(garbage first,垃圾优先)收集器是并发收集器,从 JDK1.7 开始支持,能进行 OldGC 和 YoungGC。Old 区采用标记整理算法,Young 区采用复制算法。
G1 收集器没有固定的 Old、Young、Eden、Survivor 区,而是将内存分为一个个大 小相等的 Region(格子,1Mb~32Mb)。每次垃圾回收后,Region 的用途可以发生改变, 提高了内存的灵活性和利用率。
G1 收集器可以根据开发者设置的参数,停顿时间的期望值,优先筛选回收存活的对象 比较少,垃圾对象比较大的区域 Region,可以把更多空余的空间释放出来。
ZGC 从 JDK11 开始支持,目前还是一个实验性版本,原理类似 G1。是目前收集效率 最高的垃圾收集器,平均暂停时间为 0.05 毫秒。
如何选择垃圾收集器- 优先让服务器自己来选择
- 如果内存小于 100M,使用串行收集器
- 如果服务器是单核,并且没有停顿时间要求,使用串行收集器
- 如果允许停顿时间超过 1 秒,选择并行收集器
- 如果停顿时间不能超过 1 秒,使用并发收集器



