JVM垃圾回收算法
前一篇提到了判断内存对象是否可回收的两种算法:Reference Counting GC、Tracing GC。
从垃圾内存的回收角度看,大部分垃圾收集器遵从了分代收集(Generational Collection)理论。其包含 3 个经验假说:
- 绝大多数对象都是朝生夕死
- 熬过越多次垃圾收集过程的对象就越难消亡
- 跨代引用相对于同代引用来说仅占极少数
基于以上假说
- 常用的收集器把 Java Heap 划分为不同的区域,根据对象熬过的回收次数,分配到不同的内存区域
- 绝大部分新分配的对象生存时间较短,放到一个区域
- 多次熬过垃圾回收的对象放到一个区域,低频回收
基于此
- Java Heap 一般划分了新生代(Young Generation)和老年代(Old Generation)
- 一般新生代分配新对象,熬过多次回收的对象移到老年代
- 建立 Remembered Set,把老年代划分为若干小块,标识出跨代引用的小块在新生代 GC 时被纳入 GC Roots 扫描,解决跨代引用问题
以上过程中
- 新生代的垃圾收集,叫:Minor GC 或 Young GC
- 老年代的垃圾收集,叫:Major GC 或 Old GC
- 新生代 + 部分老年代垃圾收集,叫:混合收集,Mixed GC
- 整堆 Heap + 方法区的收集,叫:Full GC
针对新生代与老年代回收垃圾内存的特点,提出了 3 种不同的算法:
1、标记-清除算法(Mark-Sweep)
标记需回收对象,统一回收;或标记存活对象,回收未标记对象。
缺点:
- 大量对象需要标记与清除时,效率不高
- 标记、清除产生的大量不连续内存碎片,导致无法分配大对象
2、标记-复制算法(Mark-Copy)
可用内存等分两块,使用其中一块 A,用完将存活的对象复制到另外一块 B,一次性清空 A,然后改分配新对象到 B,如此循环。
缺点:
- 不适合大量对象不可回收的情况,换句话说就是仅适合大量对象可回收,少量对象需复制的区域
- 只能使用内存容量的一半,浪费较多内存空间
3、标记-整理算法(Mark-Compact)
标记存活的对象,统一移到内存区域的一边,清空占用内存边界以外的内存。
缺点:
- 移动大量存活对象并更新引用,需暂停程序运行
不同的垃圾收集器,在不同的内存区域,对这 3 种算法进行了取舍与整合。
【Java学习资源】整理推荐
- MAT 分析堆内存快照
- jclasslib 查看类信息
- 增大 MAT 堆内存
- JVM 常用配置参数(Java 8)
- 40 道JVM面试题解答
- JVM 问题排查常用指令
- jvisualvm 远程连接服务器 JVM
- 字节码指令分类
- -verbose:gc 和 -XX:+PrintGC 的区别
- JVM字节码指令表
- 图解 Class 文件结构
- Class 文件的结构
- JVM 故障处理工具列表
- HotSpot 内存分配的主要规则
- 开启 GC 日志
- 垃圾收集器及特点
- JVM垃圾回收算法
- 什么样的 Java 对象会被当垃圾回收?
- 内存溢出复现
- HotSpot VM 中对象的内存分析
- JVM 控制的内存区域
- JVM家族
- Java 的发展史
- 常见 JVM dump 指令
【Java面试题与答案】整理推荐
- 基础与语法
- 集合
- 网络编程
- 并发编程
- Web
- 安全
- 设计模式
- 框架
- 算法与数据结构
- 异常
- 文件解析与生成
- Linux
- MySQL
- Oracle
- Redis
- Dubbo
还没有评论,来说两句吧...