单线程Serial
public class Book{
private String name;
private String author;
public Book(String name, String author) {
this.name = name;
this.author = author;
}
public void page(long no){
String page="page_"+no;
System.out.println(page);
}
}
public class Test {
public static void main(String[] args) {
Book book=new Book("jvm","agan");
long n=0;
while (true){
book.page(n);
++n;
}
}
}
main方法的栈帧引用了堆的book对象
大量的page产生了大量的临时对象,即大量ptemp对象,大量的ptemp对象垃圾
大量的ptemp对象很快就把年轻代沾满。
目前只有一条线程运行,实际线上系统一般是100-200条线程运行,并不停地产生垃圾对象!
关于年轻代满了,该如何处理?
答案是:垃圾回收器
为了提升垃圾回收性能,垃圾回收器分为年轻代回收器 和 老年代回收器
当年轻代满的时候,会触发ygc
- 垃圾收集器,先把所有工作线程挂起,所有工作线程进入安全点SafePoint后,当前处于STW状态。
- gc线程,采用复制算法干了3件事,
- 把eden区的存活对象复制到survivor区,
- 把survivor的对象年龄 》 15 或survivor满了,复制到old区
- 清空eden
当gc线程执行结束后,工作线程被唤醒,继续处于running状态。
以上原理就是Serial垃圾回收器
Serial是1999发布的,年代最悠久的垃圾收集器,于jdk1.3之前就开始使用。
特点:分代:年轻代
- 工作方式:单线程串行回收
- 算法:复制算法
- 性能设计:停顿时间短(响应速度快)
应用场景:
单CPU单核的环境下,适用于Client模式下的年轻代收集器。
现在大家只要了解就可以了,现在市面上基本找不到单CPU单核了,所以这个收集器在当今已经过时了。
ParNew垃圾回收器
ParNew它是Serial收集器的多线程版本
特点:
- 分代:年轻代
- 工作方式:多线程并行独占式回收
- 算法:复制算法
- 性能设计:停顿时间短(响应速度快)
应用场景:
适用于多核多CPU的环境下,并且需要与用户交互的程序(例如,客户端桌面游戏,非常高的响应速度用户体验)的年轻代收集器。
使用参数:
-XX:+UseParNewGC,表示年轻代使用了ParNew收集器。
-XX:ParallelGCThreads,表示设置gc线程数量,默认CPU核数
-XX:MaxGCPauseMillis,表示最大停顿时间(即STW的时间)。单位是毫秒。对用户来说,停顿时间越短体验越好,但使用该参数需要谨慎。(默认值为0,代表没有限制停顿时间
官方建议尽量不要去设置它,原因是为满足最小的暂停时间,VM将设置更小的堆,以存储相对少量的对象,来提升回收速率,会导致更高频率的GC。
Parallel垃圾回收器
Parallel它和ParNew回收一样,唯一的区别就是性能设计采用了高吞吐量。
特点:
- 分代:年轻代。
- 工作方式:多线程并行独占式回收
- 算法:复制算法
- 性能设计:高吞吐量
- jdk8默认垃圾收集器
应用场景:
高吞吐量适用于多核多CPU的环境下,服务端的高并发(例如,互联网微服务)的年轻代收集器。
使用参数:
-XX:+ UseParallelGC,标识年轻代使用了Parallel Scavenge收集器。