11-选择合适的垃圾收集器
2021-06-11 本文已影响0人
紫荆秋雪_文
一个垃圾收集器除了垃圾收集这个本职工作之外,它还要负责堆的管理与布局、对象的分配、与解释器的协作、与编译器的协作、与监控子系统协作等职责,其中至少堆的管理和对象的分配这部分功能是Java虚拟机能够正常运作的必要支出,是一个最小化功能的垃圾收集器也必须实现的内容。
一、收集器的权衡
选取时主要考量因素
- 应用程序的主要关注点是什么?如果是数据分析、科学计算类的任务,目标是能尽快算出结果,那吞吐量就是主要关注点;如果是SLA应用,那停顿时间直接影响服务质量,严重的甚至会导致事务超时,这样延时就是主要关注点;而如果是客户端应用或者嵌入式应用,那垃圾收集的内存占用则是不可忽视的。
- 运行应用的基础设施如何?譬如硬件规格,要涉及的系统架构是x86-32/64、SPARC还是ARM / Aarch64处理器的数量多少,分配内存的大小;选择的操作系统是Linux、Solaris还是Windows等。
- 使用JDK的发行商是什么?版本号是多少?是ZingJDK/Zulu、OracleJDK、Open-JDK、OpenJ9或是其他公司的发行版?
二、虚拟机及垃圾收集器日志
- 在JDK9以前,HotSpot并没有提供统一的日志处理框架,虚拟机各个功能模块的日志开关分布在不同的参数上,日志级别、循环日志大小、输出格式、重定向等设置在不同功能上都要单独解决。
- 直到JDK9,这种混乱不堪的局面才终于消失,HotSpot所有功能的日志都收归到了“-Xlog”参数上,这个参数的能力也相应被极大拓展了
-Xlog[:[selector][:[output][:[decorators][:output-options]]]]
- 命令行中最关键的参数是选择器(Selector),它由标签(Tag)和日志级别(Level)共同组成。
- 标签(Tag)可理解为虚拟机中某个功能模块的名字,它告诉日志框架用户希望得到虚拟机哪些功能的日志输出
- 垃圾收集器的标签名称为"gc",HotSpot全部支持的功能模块标签名如下
add,age,alloc,annotation,aot,arguments,attach,barrier,biasedlocking,blocks,bot,breakpoint,bytecode,
- 日志级别从低到高,共有Trace、Debug、Info、Warning、Error、Off六种级别,日志级别决定了输出信息的详细程度,默认级别为Info,HotSpot的日志规则与Log4j、Slf4j这类Java日志框架大体上市一直的。
- 输出日志附加额外内容,包括
- time:当前日期和时间
- uptime:虚拟机启动到现在经过的时间,以秒为单位
- timemillis:当前时间的毫秒数,相对于System.currentTimeMillis()的输出
- uptimemillis:虚拟机启动到现在经过的毫秒数
- timenanos:当前时间的纳秒数,相当于System.nanoTime()的输出
- uptimenanos:虚拟机启动到现在经过的纳秒数
- pid:进程ID
- tid:线程ID
- level:日志级别
- tags:日志输出的标签集
实例——JDK9的G1收集器
- 查看GC基本信息,在JDK9之前使用-XX: +PrintGC, JDK9之后使用-Xlog: gc
bash-3.2$ java -Xlog:gc GCTest [0.222s][info][gc] Using G1 [2.825s][info][gc] GC(0) Pause Young (G1 Evacuation Pause) 26M->5M(256M) 355.623ms [3.096s][info][gc] GC(1) Pause Young (G1 Evacuation Pause) 14M->7M(256M) 50.030ms [3.385s][info][gc] GC(2) Pause Young (G1 Evacuation Pause) 17M->10M(256M) 40.576ms
- 查看GC详细信息,在JDK9之前使用-XX: +PrintGCDetails,在JDK9之后使用-X-log: gc*
bash-3.2$ java -Xlog:gc* GCTest [0.233s][info][gc,heap] Heap region size: 1M [0.383s][info][gc ] Using G1 [0.383s][info][gc,heap,coops] Heap address: 0xfffffffe50400000, size: 4064 MB, Compressed Oops mode: Non-zero based: 0xfffffffe50000000, Oop shift amount: 3 [3.064s][info][gc,start ] GC(0) Pause Young (G1 Evacuation Pause) gc,task ] GC(0) Using 23 workers of 23 for evacuation [3.420s][info][gc,phases ] GC(0) Pre Evacuate Collection Set: 0.2ms [3.421s][info][gc,phases ] GC(0) Evacuate Collection Set: 348.0ms gc,phases ] GC(0) Post Evacuate Collection Set: 6.2ms [3.421s][info][gc,phases ] GC(0) Other: 2.8ms gc,heap ] GC(0) Eden regions: 24->0(9) [3.421s][info][gc,heap ] GC(0) Survivor regions: 0->3(3) [3.421s][info][gc,heap ] GC(0) Old regions: 0->2 [3.421s][info][gc,heap ] GC(0) Humongous regions: 2->1 [3.421s][info][gc,metaspace ] GC(0) Metaspace: 4719K->4719K(1056768K) [3.421s][info][gc ] GC(0) Pause Young (G1 Evacuation Pause) 26M->5M(256M) 357.743ms [3.422s][info][gc,cpu ] GC(0) User=0.70s Sys=5.13s Real=0.36s [3.648s][info][gc,start ] GC(1) Pause Young (G1 Evacuation Pause) [3.648s][info][gc,task ] GC(1) Using 23 workers of 23 for evacuation [3.699s][info][gc,phases ] GC(1) Pre Evacuate Collection Set: 0.3ms gc,phases ] GC(1) Evacuate Collection Set: 45.6ms gc,phases ] GC(1) Post Evacuate Collection Set: 3.4ms gc,phases ] GC(1) Other: 1.7ms gc,heap ] GC(1) Eden regions: 9->0(10) [3.699s][info][gc,heap ] GC(1) Survivor regions: 3->2(2) [3.699s][info][gc,heap ] GC(1) Old regions: 2->5 [3.700s][info][gc,heap ] GC(1) Humongous regions: 1->1 [3.700s][info][gc,metaspace ] GC(1) Metaspace: 4726K->4726K(1056768K) [3.700s][info][gc ] GC(1) Pause Young (G1 Evacuation Pause) 14M->7M(256M) 51.872ms [3.700s][info][gc,cpu ] GC(1) User=0.56s Sys=0.46s Real=0.05s
-
JDK9前后日志参数变化
image.png
image.png
三、垃圾收集器参数总结
image.pngimage.png