2023-03-23 04:52:06
GC垃圾回收机制是Java中自动管理内存的核心机制,通过判断垃圾对象并采用特定算法回收其占用的内存空间,以解决内存有限性与对象生命周期不一致的问题。 以下是具体机制与实现细节:
一、垃圾对象的判断方法引用计数法原理:为对象添加引用计数器,每被引用一次计数器+1,引用失效时-1。计数器为0的对象视为垃圾。特点:Python等语言采用此方法,但无法处理循环引用问题(如两个对象互相引用但无外部引用时无法被回收)。
可达性分析法原理:以“GC Roots”对象为起点,通过引用链搜索。若对象与GC Roots无任何引用链相连(不可达),则视为垃圾。GC Roots对象类型:
虚拟机栈(栈帧)中引用的对象
方法区中静态属性引用的对象
方法区中常量引用的对象
本地方法栈引用的对象

标记-清除算法流程:先标记所有需回收对象,再统一清除。缺点:
效率问题:标记和清除步骤的效率均较低。
空间问题:产生大量不连续内存碎片,可能导致大对象分配失败而提前触发GC。

标记-整理算法优化点:在标记清除基础上,将存活对象向一端移祥裂动,直接清理端边界外的内存,避免碎片问题。适用场景:老年代对象回收(存活率高,需减少空间浪费)。

复制算法原理:将内存分为两块,每次仅使用一块。回收时将存活对象复制到另一块,清空当前块。特点:以空间换时间,适合新生代(对象存活率低)。实现细节:新生代分为Eden、S0(Survivor 0)、S1(Survivor 1)三区。春耐对象首次进入Eden区,Young GC后存活对象移至S0,清空Eden;下次GC时将Eden和S0的存活对象移至S1,清空Eden和S0,如此交替使用S0和S1。
JVM内存分区
线程独享区:虚拟机栈、程序计数器、本地方法栈(程序结束时自动回收)。
共享区:堆(对象存放区,垃圾回收主要发生在此)、方法区(存放永久变量,回收频率低)。

堆内存分代回收
新生代:存放“朝生夕死”对象,使用复制算法。
对象首次分配在Eden区,经Young GC后存活对象移至Survivor区(S0/S1)。
经过15次Young GC仍存活的对象晋升至老年代。
老年代:存放存活时间长的对象,使用标记-整理算法。
Full GC时触发标记-整理,需停止JVM运行(Stop-The-World),应尽量避免。
分代选择依据:新生代对象存活率低,复制算法效率高;老年代对象存活率高,复制成本大,标记-整理更优。
新生代:复制算法(低存活率场景高效)。
老年代:标记-整理算法(高存活率场景减少空间浪费)。