前言
垃圾收集(garbage collection,GC)作用于java堆(主要)和方法区。
垃圾收集算法有三种
标记-清除算法,复制算法,标记-整理算法
1,标记-清除算法(mark-sweep)
先标记所有需要回收的对象,在标记完成后统一回收被标记的对象
缺点:1,效率不是很高。2,清除后会产生大量不连续的内存碎片
2,复制算法 ( copying )
它将可用内存分为两块,每次只使用其中的一块,当这块的内存用完了,就将还存活的对象复制到另一块上面去,然后把使用过的内存一次性清理掉。这样效率较高,现在很多虚拟机采用这种复制算法来回收新生代(大部分对象都是朝生夕死的)(大概可以理解为活着的比较少,复制代价小),新生代一般分为一块大的Eden区和两个较小的survivor区,默认比例为8:1,这个算法会有少量内存浪费,如果复制到survivor不够用,需要依赖老年代进行分配担保。
3,标记-整理算法( mark-compact )
根据老年代的特征,提出标记-整理算法,标记过程与标记-清除算法一样,但是后面整理就是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。老年代存活率比较高,而且没有额外的空间对他进行分配担保,所以最好剩余内存大一些,所有一般用标记清除和标记整理算法。
重要名词解释:
1,GC roots
或者说tracing GC的“根集合”,就是一组必须活跃的引用。
例如说,这些引用可能包括:
• 所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用;换句话说,当前所有正在被调用的方法的引用类型的参数/局部变量/临时值。VM的一些静态数据结构里指向GC堆里的对象的引用,例如说HotSpot VM里的Universe里有很多这样的引用
• JNI handles,包括global handles和local handles
•(看情况)所有当前被加载的Java类
•(看情况)Java类的引用类型静态变量
•(看情况)Java类的运行时常量池里的引用类型常量(String或Class类型)
•(看情况)String常量池(SringTable)里的引用
判断对象是否存活有两种比较常见的方法:引用计数法(有缺陷)与可达性分析算法。枚举跟节点进行可达性分析,确定对象的存活情况
2,安全点
在OopMap(需要空间成本)的协助下,HotSpot可以快速准确的完成GC Roots枚举。为了空间成本不那么高,只有在特定的位置才有OopMap记录信息,这些位置阻塞是安全的。安全点意味着对应根枚举来说,在该点阻塞是安全的。安全区域是指在一段代码之中,引用关系不会发生变化,在这个区域的GC都是安全的
垃圾收集器
1,Serial收集器 / Serianl old 收集器
他是最基本收集器,而且是单线程的,他工作的时候所有的线程都要停掉,serial old是serial的老年代版本
2,parNew收集器
他是serial收集器的多线程版本,可以使用多线程进行垃圾回收
3,parallel Scavenge / parallel old 收集器
parallel Scavenge 是一个新生代收集器,使用复制算法并且多线程
他的关目标是达到一个可控制的吞吐量,高效的利用cpu时间,尽快完成程序的运算任务,适合后台运算不需要太多交互,parallel old 是老年代版本
4,CMS收集器
CMS(并发标记清除)收集器是一种以获得最短回收停顿时间d