STW:stop-the-world
—java垃圾回收器在执行时,会停止所有的应用程序的执行,使系统不会产生新的垃圾,这个现象叫做STW
垃圾回收器分为串行回收器和并行回收器
串行回收器
串行回收器分为新生代串行和老年代串行
特点:
1.使用单线程进行回收
2.独占式(STW)垃圾回收
新生代使用的是复制算法
老年代使用的是标记压缩算法
client默认为串行
设置参数:
-XX:+UseSerialGC 新生代和老年代使用串行
-XX:+UseParNewGC 新生代使用ParNew 老年代使用串行
-XX:+UseParallelGC 新生代使用Parallel 老年代使用串行
public class SerialGC{
public static void main(String[] args) {
for(int i=0;i<100000;i++){
new String("Jim"+i);
}
}
}
并发回收器:
新生代:
ParNew回收器:简单的将串行回收器多线程化独占式
使用参数:
-XX:+UseParNewGC 新生代使用ParNew,老年代使用串行
-XX:+UseConcMarkSweepGC 新生代使用ParNew 老年代使用串行
-XX:ParallelGCThreads 指定线程数
代码:
public class ParNew{
public static void main(String[] args) {
for(int i=0;i<100000;i++){
new String("Tom"+i);
}
}
}
Parallel使用复制算法的并行回收器,注意系统的吞吐量
参数:
-XX:+UseParallelGC 新生代使用parallel,老年代使用串行
-XX:+UseParallelOldGC 新生代使用parallel,老年代使用parallelOldGC
-XX:MaxGCPauseMillis 设置最大垃圾回收集停顿时间
-XX:GCTimeRatio 设置吞吐量 0-100
拿出不超过1/(n+1)的时间用于垃圾回收
-XX:+UseAdaptiveSizePolicy 根据当时的情况调节新生代,eden和survivor的比例
public class Parallel{
public static void main(String[] args){
for(int i=0;i<100000;i++){
new String("Jeff"+i);
}
}
}
老年代:
ParallelOldGC一种多线并发的收集器和parallel一样只是作用区域不一样
一个作用于新声代,一个作用于老年代
参数:
使用标记压缩算法
-XX:+UseParallelOldGC 新生代Parallel 老年代ParallelOldGC
-XX:ParallelThreads 指定线程数量
例子代码:https://github.com/Ericjeff/JVM/tree/master/parallelOld
jar:https://github.com/Ericjeff/JVM/blob/master/cglib-nodep-2.2.jar
CMS:并发标记清除,主要关注系统的停顿时间,CMS不是全独占式的,而是部分独占式的
工作步骤:
初始标记---->STW:标记根对象
并发标记
预处理--->清理前的准备和停顿时间(重新标记)
重新标记--->STW
并发清除--->清除垃圾
并发重置
初始标记,并发标记,重新标记都是为了标记出需要回收的对象,并发清除则是
在标记后清除回收垃圾对象,并发重置是在垃圾回收完成后,重新初始化CMS
数据结构和数据
预处理除了作准备和检查以外,还会尝试控制一次停顿时间,一次避免与
新生代GC连续发生(就是新生代发生GC,CMS就立即进行重新标记),导致停顿时间过长
参数:
-XX:+UseConcMarkupSweepGC 新生代为ParNew 老年代为CMS
-XX:-CMSPrecleaningEnabled 不惊醒预处理
-XX:ConGCThreads 指定线程数
-XX:CMSInitiatingOccupancyFraction 指定发生CMS的阈值
-XX:+UseCMSCompactAtFullCollection 在CMS后启动一次碎片整理
-XX:CMSFullGCsBeforeCompaction 进行多少次CMS后,进行一次内存压缩
public class CMS{
public static void main(String[] args) {
for(int i=0;i<10000;i++){
byte[] b = new byte[1024*1024*3];
}
}
}
/**
* java -Xmx10m -Xms10m -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC CMS
*/
G1回收器:
是jdk1.7中正式使用的全新垃圾回收器,G1回收器拥有独有的回收策略。
从分代上看,它会区分年轻代和老年代,
从对结构上看,它并不要求整个eden区,年轻代或老年代连续,它使用分
区算法
作为CMS的长期替代方案
优点:
并发性:多个线程同时进行工作
并行性(部分工作与应用程序同时进行),
分代GC(同时兼顾新生代和老年代),
空间整理(每次回收都进行对象复制),
可预见性(可以较好的控制全局停顿)
工作步骤:
新生代GC
并发标记周期
混合收集
可能会进行全Full GC
并标记周期:(将需要回收的区域记录到回收集中(Collections Sets))
初始标记(STW):标记跟节点可达对象,伴随一次新生代GC。 (会生成
存货对象快照(SATB:Snapshot-At-The-Beginning))
跟区域扫描:扫面从survivor直接可达老年区的对象,并标记
并发标记:并发查找整个堆存活的对象
重新标记(STW):对标记结果进行纠正
独占清理:(STW) 计算各区域存活对象和GC回收比例并进行排序,识别
混合回收的区域,更新记忆集(Remembered Set),标记混合区域,并在
再混合回收
并发清除阶段:清除完全空闲区域
初始标记,重新标记,独占清理都是STW
混合回收:回收并发标记周期标记的垃圾
参数:
-XX:+UseG1GC 使用G1
-XX:MaxGCPauseMillis 最大停顿时间
-XX:ParallelGCThreads 线程数
-XX:InitiatingHeapOccupancyPercent 触发G1的阈值
public class G1{
public static void main(String[] args) {
for(int i=0;i<100;i++){
byte[] b = new byte[1024*1024];
byte[] b1 =new byte[1024*100];
}
}
}
/**
* java -Xmx10 -Xms10 -XX:+PrintGCDetails -XX:+UseG1GC G1
*/