### 分代收集算法\(Generational Collection\)
分代搜集算法是针对对象的不同特性,而使用适合的算法
### 增量回收
在对实时性要求很高的程序中,比起缩短GC的平均中断时间,往往更重视缩短GC的最大中断时间。例如,在机器人的姿势控制程序中,如果因为GC而让控制程序中断了0.1秒,机器人可能就摔倒了。或者,如果车辆制动控制程序因为GC而延迟响应的话,后果也是不堪设想的。在这些对实时性要求很高的程序中,必须能够对GC所产生的中断时间做出预测。例如,可以将“最多只能中断10毫秒”作为附加条件。在一般的GC算法中,作出这样的保证是不可能的,因为GC产生的中断时间与对象的数量和状态有关。
因此,为了维持程序的实时性,不等到GC全部完成,而是将GC操作细分成多个部分逐一执行。这种方式被称为增量回收(Incremental GC)。在增量回收中,由于GC过程是渐进的,在回收过程中程序本身会继续运行,对象之间的引用关系也可能会发生变化。如果已经完成扫描和标记的对象被修改,对新的对象产生了引用,这个新对象就不会被标记,明明是“存活”对象却被回收掉了。在增量回收中为了避免这样的问题,和分代回收一样也采用了写屏障。当已经被标记的对象的引用关系发生变化时,通过写屏障会将新被引用的对象作为扫描的起始点记录下来。由于增量回收的过程是分步渐进式的,可以将中断时间控制在一定长度之内。另一方面,由于中断操作需要消耗一定的时间,GC所消耗的总时间就会相应增加,正所谓有得必有失
### 并行回收
最近的计算机中,一块芯片上搭载多个CPU核心的多核处理器已经逐渐普及。不仅是服务器,就连个人桌面电脑中,多核CPU也已经成了家常便饭。例如美国英特尔公司的Core i7就拥有6核12个线程。在这样的环境中,就需要通过利用多线程来充分发挥多CPU的性能。并行回收正是通过最大限度利用多CPU的处理能力来进行GC操作的一种方式。并行回收的基本原理是,是在原有的程序运行的同时进行GC操作,这一点和增量回收是相似的。不过,相对于在一个CPU上进行GC任务分割的增量回收来说,并行回收可以利用多CPU的性能,尽可能让这些GC任务并行(同时)进行。由于软件运行和GC操作是同时进行的,因此就会遇到和增量回收相同的问题。为了解决这个问题,并行回收也需要用写屏障来对当前的状态信息保持更新。不过,让GC操作完全并行,而一点都不影响原有程序的运行,是做不到的。因此在GC操作的某些特定阶段,还是需要暂停原有程序的运行。在多核化快速发展的现在,并行回收也成了一个非常重要的话题,它的算法也在不断进行改善。在硬件系统的支持下,无需中断原有程序的完全并行回收器也已经呼之欲出。今后,这个领域相当值得期待
- 前言
- Write once, run anywhere
- 概述
- JAVA虚拟机
- JVM整体结构
- JVM架构模型
- JVM虚拟机分类
- HotSpot VM
- JRockit
- IBM-J9
- Azul/zing VM
- Taobao VM
- Dalvik VM
- Graal VM
- JAVA源码编译机制
- Javac编译器
- 分析和输入到符号表
- 注解处理
- 语义分析和生成class文件
- ECJ编译器
- 类执行机制
- 字节码解释执行
- 栈顶缓存
- 部分栈帧共享
- 编译执行
- 即时编译器
- C1 Compiler
- C2 Compiler
- Graal编译器
- C1与C2编译器
- AOT
- 编译优化
- 字符串优化
- 方法内联
- 逃逸分析
- 同步消除
- 标量替换
- 栈上分配
- 去虚拟化/逆优化
- 多层编译
- JVM编译策略
- OSR编译
- 冗余削除
- CodeCache
- 常量编译优化
- JVM运行时数据区
- 程序计数器
- JAVA虚拟机栈
- 栈帧
- 局部变量表
- 操作数栈
- 本地方法栈
- Java调用native方法
- JVM Stacks && Native Stacks
- 堆-Heap
- 方法区(Method Area)
- 运行时常量池
- 常量传播优化
- MetaSpace
- 直接内存
- StackOverflowError
- 递归方法
- OutOfMemoryError
- 本地内存溢出
- 执行引擎
- 运行时数据区关联关系
- jdk8内存结构
- JMM内存模型
- JAVA内存模型
- JMM八种操作指令
- 内存屏障
- 指令重排
- as-if-serial语义
- Happen-Before规则
- 数据依赖性
- 原子性、可见性与有序性
- 伪共享
- CPU三级缓存
- 缓存行
- MESI协议
- Java中的伪共享
- ConcurrentHashMap伪共享解决方案
- 虚拟机对象
- 对象创建原理
- 对象内存布局
- 对象头
- 实例数据
- 对象的访问定位
- 垃圾收集器与内存分配策略
- GC相关概念
- TLAB
- JVM GC工作原理
- 内存管理
- JAVA引用分类
- 死亡标记
- 回收方法区
- 三色标记算法
- 垃圾收集算法
- 标记-清除算法
- 标记-整理算法
- 复制算法
- 分代收集算法
- HotSpot算法实现
- STW
- 垃圾收集器
- 常见的垃圾收集器
- 垃圾收集器分类
- Serial收集器
- Serial Old收集器
- ParNew收集器
- Parallel Scavenge收集器
- Parallel Old收集器
- CMS收集器
- CMS完整收集过程
- Card Table
- G1收集器
- 分代收集
- 空间整合
- 可预测的停顿时间模型
- G1&CMS
- 主要参数说明
- G1适用场景
- Remembered Set
- G1垃圾回收的过程
- G1优化建议
- Shenandoah
- ZGC
- 垃圾收集器特点
- GC日志
- GC策略的评价指标
- jvm card table数据结构
- 对象生存轨迹
- 类文件结构
- 魔数
- 版本号
- 常量池
- 访问标志
- 父类索引
- 接口集合
- 字段集合
- 方法集合
- 属性集合
- 类加载机制与类的初始化
- Java代码执行流程
- 类加载过程
- 抽象类ClassLoader
- 常见类加载器
- BootstrapClassLoader
- 自定义类加载器
- 线程上下文类加载器
- 双亲委派模型
- Tomcat类加载机制
- ServiceLoader
- 类的初始化
- 常见的JVM类加载异常
- ClassNotFoundException
- NoClassDefFoundError
- LinkageError
- ClassCastException
- 虚拟机性能调优监控与故障处理工具
- CPU利用率高/飙升
- 排查及解决方案
- 上下文切换
- GC问题定位解决方案
- prommotion failed
- FullGC频繁
- youngGC
- 内存问题
- 内存溢出和内存泄漏
- 内存溢出
- 栈溢出
- 堆溢出
- 对外内存溢出
- 内存泄漏
- 磁盘问题
- 线上问题解决方案
- 不定期出现的接口耗时现象
- 线程池异常
- 死锁问题
- JVM调优
- jvm参考配置
- jvm-jstat
- jvm-jmap
- jvm-jstack
- jinfo
- jps
- 虚拟机的退出
- Shutdown Hook
- JVM指令
- 附录
- 常用JVM指令
- Class文件版本号
- Class文件格式
- 方法访问标识
- jvm常量池
- 类或接口的访问标识
- 描述符标识字符含义
- 字段访问标识
- Java程序与Docker容器环境
- 基准测试