JVM组成

JVM由哪几个部分(模块儿)组成呢?

类加载系统、运行时数据区、Java执行引擎、JNI本地方法接口、本地方法库

其中Java执行引擎就由 解释器、JIT即时编译器、GC 组成

解释执行 和 编译执行的本质区别? 计算机是无法识别我们写的程序的,因为计算机只认识 01 二进制代码,也就是机器码。 所以我们写的程序,需要通过转化为 机器码 后计算机才能执行,编译和解释也就是转换过程的不同。 编译执行:一次将代码文件通过编译器转化为机器码,以后都不用再次进行编译 解释执行:每次运行时,都是执行一句,就交给解释器解释一句 优缺点: 启动速度:解释执行更快,因为不需要进行编译操作 运行效率:编译程序只需编译一次得到机器码,便每次都直接执行,所以更快一点 兼容性:编译执行在不同类型机器上需要必须重新编译,而不能直接执行 总的来说:如果比作吃饭的话,编译执行就是一桌子菜,直接可以吃,而解释执行就像吃火锅,需要边煮边吃

常见回收器

image.png

其中 新生代中的回收器都是通过 复制算法, 老年代的回收器除了 CMS 是标记清楚, 其余都是通过 标记整理 算法, 整堆回收器 : 一个Region中是 标记-清除 算法 , 2 个 Region 之间是复制算法

Serial - SerialOld

image.png
serial 是最基本的, 历史最悠久的收集器

特点: 单线程、简单高效(与其他收集器的单线程相比),对于限定单个CPU的环境来说,Serial收集器
由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。收集器进行垃圾回收
时,必须暂停其他所有的工作线程,直到它结束(Stop The World)。

适用场景: 单核机器, client模式下的 虚拟机

ParNew

ParNew 是许多运行在 Server 模式下的虚拟机的首选新生代收集器, 因为它是除了 Serial Old 外, 唯一能和 CMS 搭配适用的新生代收集器

image.png

ParNew 和 Serial 唯一的区别就是 ParNew 使用了多线程进行垃圾回收过程

Parallel Scavenge

与 ParNew 一样是多线程进行垃圾回收的, 同样存在 STW, 同样使用复制算法

但是 Parallel Scavenge 可以达到一个可控的 吞吐量 (吞吐量 = 执行用户代码时间 / (垃圾回收时间 + 运行用户代码时间))

之所以能达到可控的吞吐量, 是由于 GC自适应调节策略, 这也是与其他垃圾回收器的一个重要区别

gc自适应调节策略

PS 收集器可以通过参数设置开启自适应调节, 之后就不需要手动指定 新生代大小, 以及 Eden去与 Survivor 的比例, 以及晋升老年代的年龄, 虚拟机会根据系统的运行状况收集性能监控信息, 动态设置这些参数以提供最右的停顿时间和最高的吞吐量, 这种调节方式称为 GC 的自适应调节策略

可以通过两个参数 控制 吞吐量

XX:MaxGCPauseMillis 控制最大的垃圾收集停顿时间 XX:GCRatio 直接设置吞吐量的大小。

Serial Old

是 Serial 的老年代版本, 同样的单线程回收器, 采用标记整理算法

可以作为 CMS 收集器的后备方案, 在并发收集出现 Concurrent Mode Failure时使用

Parallel Old

采用多线程处理, 使用 标记整理算法

使用场景: 注重高吞吐量以及CPU资源敏感的场合 , 所以注重高吞吐量的场合可以优先考虑 Parallel Scavenge + Parallel Old 收集器

CMS

CMS 是第一个使用 并发模式收集的收集器

特点 : 标记清除算法 , 并发收集, 低停顿

应用场景 : 更加注重相应速度的服务, 如 web 程序, B.SS 服务

过程

初始标记 : 标记 GC roots 能直接到的对象, 速度很快, 但是仍然存在 STW
并发标记 : 进行 GC roots tracing 过程, 找到存活对象, 并且此阶段不会造成STW, 用户线程可以执行
重新标记 : 为了修正并发标记过程期间因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录. 仍然存在 STW 过程
并发清除 : 对标记对象进行清除

CMS收集器的内存回收过程是与用户线程一起并发执行的
image.png

缺点:

  1. 对CPU资源非常敏感
  2. 无法处理浮动垃圾, 可能出现 Concurrent Model Failure 失败, 而导致另一次FUllGC的产生, 并且调用 serial old 处理
  3. 因为标记清除算法会产生空间碎片的问题, 导致大对象无法分配, 不得已提前出发一次 Full GC

G1

image.png

G1 收集器, 不在将堆内存物理的进行分区, 而是采用逻辑分区, 划分为 一个个 的 Region , 每个Region 既可以是 年老代, 也可以是新生代, 回收时不在时衡量它属于那个分代, 而是哪一块的垃圾最多, 能获取到的利益最大

四个阶段 (图片存在问题, 第四阶段也是需要停顿)

初始标记: STW
并发标记:
最终标记 : 处理并发阶段遗留的 需要短暂的暂停
筛选清除: 对各个region的回收价值和代价进行排序, 可以根据用户期望的停顿时间来指定回收计划, 可以自由选择任意多个 region 进行回收, 然后决定回收的那部分 region 复制到 空的region中 , 由于存在存活对象的移动, 所以必须要暂停用户线程

[

](#C8W19)


垃圾回收算法

标记清除

image.png
一次扫描, 遇到垃圾直接删除, 会产生内存碎片, 如果再次分配 大对象分配不下时, 就会导致提早 GC

标记整理

image.png
两次扫面: 第一次扫面首先标记垃圾对象, 第二次扫描则是将垃圾清除, 并移动复制内存对象

拷贝

image.png

将内存分为两份, 扫描的时候将存活对象有序的移动到另一侧

特点:

  1. 只扫描一次, 但是需要移动复制对象
  2. 消耗大量内存
  3. 没有内存碎片
  4. 适合在存活对象较少的场景下使用