一、基本概念
1. 垃圾
- 在运行程序中,没有任何指针指向的对象,就是需要被回收的垃圾
- 如果不及时对内存中的垃圾进行清理,那么就会一直占用内存空间,被保留的空间无法被其他对象使用,就会导致内存溢出
2. 垃圾回收的意义
- 如果不进行垃圾回收,内存迟早都会被消耗完毕
- 除了释放没用的对象,垃圾回收也可以清理内存中的记录碎片。碎片整理将所占用的堆内存移到堆的另一端,以便JVM将整理出的内存分配给新的对象
- 业务的逐渐复杂,没有GC就不能保证应用程序的正常进行。同时经常的STW,又会影响实际的需求,所以需要不断的对GC进行优化
3. 垃圾回收
4. JAVA垃圾回收
- 自动内存管理,无需开发人员手动进行内存的分配和回收,降低内存泄漏和内存溢出的风险
- 自动内存管理,开发人员可以专注于业务开发
1. 自动内存管理是黑匣子,开发人员必须了解,以便出现内存溢出时定位问题和解决问题
二、垃圾回收算法
三、垃圾标记阶段
- 堆里存放着几乎所有的Java对象实例,在GC执行之前,首先需要区分出内存中哪些是存活对象,哪些是已死亡对象
- 只有被标记死亡的对象,GC才会在执行时,释放掉其所占用的内存空间
- 当一个对象已经不再被任何的存活对象继续引用时,可以判断为已经死亡
- 包含引用计数算法和可达性分析算法
1. 引用计数算法
1. 每个对象保存一个人整型的引用计数器属性,用于记录对象被引用的情况
1.1 对于一个对象A,只要有任何一个对象引用了A, 则A的引用计数器加1
1.2 当引用失效时,引用计数器减1
1.3 对象A的引用计数器的值为0,则表示对象A不可能再被使用,就可以回收
2. 优点: 实现简单,垃圾对象方便辨识,判定效率高,回收没有延迟
3. 缺点:
3.1 需要单独的字段存储计数器,增加 存储空间的开销
3.2 每次赋值需要更新计数器,伴随着加法和减法,增加了 时间开销
3.3 致命缺陷: 无法处理循环引用的问题, 最终java的垃圾回收器中没有使用该算法