以windows系统为例,JDK版本1.8.0_251。
- 查看当前JAVA进程
D:\Java\jdk1.8.0_251\bin>jps
23776 Program
5600 Jps
D:\Java\jdk1.8.0_251\bin>
- 查看java进程使用的垃圾收集器
D:\Java\jdk1.8.0_251\bin>jmap -heap 23776
Attaching to process ID 23776, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.251-b08
using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)
Heap Configuration:
**以下是堆的相关信息,省略
D:\Java\jdk1.8.0_251\bin>
以上可以看出进程使用了G1垃圾收集器。
- 修改垃圾收集器
目前HotSpot虚拟机支持的垃圾收集器有:
- UseSerialGC Client模式下的默认收集器,使用Serial+SerialOld组合
- UseParNewGC 使用ParNew+SerialOld组合,JDK9以后不再支持
- UseConcMarkSweepGC 使用ParNew+CMS+SerialOld组合。SerialOld作为CMS并发失败的后备收集器使用
- UseParallelGC 使用Parallel Scavenge+Serial Old组合。JDK9之前Server模式下的默认收集器
- UseParallelOldGC 使用Parallel Scavenge+Parallel Old组合
- UseG1GC 使用G1收集器,JDK9后Server模式默认收集器
- UseShenandoahGC 使用Shenandoah收集器。OracleJDK不支持,只能在OpenJDK12或其他支持Shenandoah的Backport发行版使用。
- UseZGC 使用ZGC收集器。
使用方法是在虚拟机的启动参数中增加-XX:+UseXXXGC。
在eclipse下测试,使用如下死循环代码:
package deadloop.test;
public class DeadLoop {
public static void main(String[] args) {
while(true);
}
}
不加任何配置时,执行,然后在命令行查看垃圾收集器:
D:\Java\jdk1.8.0_251\bin>jps
23776 Program
23464 Jps
18924 DeadLoop
D:\Java\jdk1.8.0_251\bin>jmap -heap 18924
Attaching to process ID 18924, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.251-b08
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration:
***以下内容省略,下同
可以看出未加任何配置时,JDK1.8使用的默认收集器为Parallel Scavenge+Serial Old组合。
在eclipse的运行配置里,增加虚拟机参数UseConcMarkSweepGC:
运行后,命令行查看垃圾收集器如下:
D:\Java\jdk1.8.0_251\bin>jps
19328 DeadLoop
23776 Program
16860 Jps
D:\Java\jdk1.8.0_251\bin>jmap -heap 19328
Attaching to process ID 19328, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.251-b08
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
*****
可以看出,参数已生效,DeadLoop进程改为使用CMS收集器。其他垃圾收集器设置与此相同,在此就不一一例举了。
大家可以根据应用的需要自行选择最适合的垃圾收集器。
关于各个垃圾收集器的区别,可以参考我的上一篇博文《HotSpot虚拟机垃圾收集器-理论篇》。
最后附上上篇博文未完成的部分,关于Shenandoah与ZGC的部分。
Shenandoah与ZGC被称作低延迟垃圾收集器,是因为这两个收集器几乎所有的收集过程都可以与用户线程并发进行。
Shenandoah收集器采用了转发指针作为对象的引用指针,当一个对象未被收集前,该转发指针指向自己,但当其被整理复制之后,转发指针就会指向新的对象。以此来保证收集过程与用户线程的并发进行。
ZGC则使用了染色体指针来实现,不再对对象做特殊处理,改为在指向对象的指针上做标记。将指针的高四位提取出来存储四个标志信息,通过这些标志来确定当前对象的状态。ZGC在jdk11版本作为实验性质发布。
这两种收集器因为采用了特定技术保证了收集过程与用户线程的并发,所以停顿时间比其他收集器大幅缩减,下降到10毫秒以内。