深入理解Java虚拟机程序员Java开发那些事

《深入理解Java虚拟机》读书笔记2:垃圾收集器与内存分配策略

2017-03-19  本文已影响172人  ginobefun

国内JVM相关书籍NO.1,Java程序员必读。读书笔记第二部分对应原书的第三章,主要介绍JVM的垃圾回收算法、实现。

第三章 垃圾收集器与内存分配策略

概述

思考GC需要完成的3件事情:

再回头看看第二章介绍的Java内存运行时区域的各个部分:

对象已死吗?

在垃圾收集器进行回收前,第一件事就是确定这些对象哪些还存活,哪些已经死去。

引用计数算法

给对象添加引用计数器,当有地方引用它时就加1,引用失效就减1,为0时就认为对象不再被使用可回收。该算法失效简单,判断高效,但并不被主流虚拟机采用,主要原因是它很难解决对象之间相互循环引用的问题。

可达性分析算法

通过一系列的称为“GC Roots”的对象作为起点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),如果一个对象到GC Roots没有引用链相连,则该对象是不可用的。

可达性分析

在Java语言中,可作为GC Roots的对象包括:

再谈引用

在JDK 1.2之后,Java对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用和虚引用,这4种引用强度依次减弱。

生存还是死亡

要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize方法(如没有重写finalize方法或者已经被调用过则认为没有必要执行);如果有必要执行则将该对象放置在F-Queue队列中,并在稍后由一个由虚拟机自己建立的、低优先级的Finalizer线程去执行它;稍后GC将对F-Queue中的对象进行第二次标记,如果对象还是没有被引用,则会被回收。

但是作者不建议通过finalize方法“拯救”对象,因为它运行代价高、不确定性大、无法保证各个对象的调用顺序。

回收方法区

永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类。

一个无用的类需要满足以下三个条件:

在大量使用反射、动态代理、CGLib等ByteCode框架、动态生成JSP以及OSGI这类频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能(HotSpot提供-Xnoclassgc参数控制),以保证永久代不会溢出。

垃圾收集算法

HotSpot的算法实现

枚举根节点

安全点

安全区域

垃圾收集器

HotSpot垃圾收集器

Serial收集器

Serial收集器

ParNew收集器

ParNew收集器

Parallel Scavenge收集器

Serial Old收集器

Serial Old收集器

Parallel Old收集器

Parallel Old收集器

CMS收集器

CMS收集器

G1收集器

G1收集器

理解GC日志

GC日志

垃圾收集器参数总结

垃圾收集器参数1
垃圾收集器参数2

内存分配与回收策略

本章小结

本章介绍了垃圾回收算法、几款JDK 1.7中提供的垃圾收集器特点以及运作原理。内存回收与垃圾收集器在很多时候都是影响系统性能、并发能力的主要因素之一,然而没有固定收集器和参数组合,也没有最优的调优方法,需要根据实践了解各自的行为、优势和劣势。

系列读书笔记

扫一扫 关注我的微信公众号
上一篇 下一篇

猜你喜欢

热点阅读