最近在看JVM垃圾收集相关的内容,发现了《深入理解JAVA虚拟机》的描述不太容易理解;原文如下:
GCTimeRatio参数的值应当是一个大于0且小于100的整数,也就是垃圾收集时间占总时间的比率,相当于是吞吐量的倒数。如果把此参数设置为19,那允许的最大GC时间就占总时间的5%(即1/(1+19)),默认值为99,就是允许最大1%(即1/(1+99))的垃圾收集时间。
而书中吞吐量的公式为:吞吐量=用户程序的运行时间/ (垃圾收集时间 + 用户程序的运行时间);和上面提到的计算公式不匹配;所以感觉这里的描述是有问题的;后来查询官方文档:The Parallel Collector,官方关于GCTimeRatio的描述如下:
Throughput: The throughput goal is measured in terms of the time spent doing garbage collection versus the time spent outside of garbage collection, referred to as Application time. The goal is specified by the command-line option -XX:GCTimeRatio=<N>, which sets the ratio of garbage collection time to application time to 1 / (1 + <N>)
For example, -XX:GCTimeRatio=19 sets a goal of 1/20 or 5% of the total time in garbage collection. The default value is 99, resulting in a goal of 1% of the time in garbage collection
描述中有一句话比较关键:which sets the ratio of garbage collection time to application time to 1 / (1 + <N>); which指代GCTimeRatio参数,后面的描述说明可以通过这个参数计算垃圾收集时间占用应用程序时间的比例,公式为 : 1/(1+ GCTimeRatio的值)。从字面上可以看出,GCTimeRatio的作用是为了计算垃圾收集的时间占用程序运行时间的值;而GCTimeRatio应该理解为用户程序的运行时间与垃圾收集时间的比例,即GCTimeRatio = userTime/GCTime, 其中userTime表示用户程序运行时间,GCTime表示垃圾收集程序运营时间;
下面进行验证
当GCTimeRatio=19时, 我们通过GCTimeRatio = userTime/GCTime(对参数进行假设的公式)可以得到userTime= 19GCTime, 再代入吞吐量计算公式:
公式1: 吞吐量=用户程序的运行时间/ (垃圾收集时间 + 用户程序的运行时间)
公式2:垃圾的运行时间/ (垃圾收集时间 + 用户程序的运行时间) + 吞吐量 = 1
代入公式1 可得 吞吐量 = userTime /(GCTime + userTime) --> 19GCTime / (GCTime + 19GCTime) --> 19/(1+19);
公式1的结果代入公式2,可得 垃圾收集的运行时间 / (垃圾收集时间 + 用户程序的运行时间) = 1- 吞吐量 = 1- [19/(1+19)] = 1/(1 + 19); 和官方描述的公式一致;
总上所述:GCTimeRatio应该理解为用户程序的运行时间与垃圾收集时间的比例,即GCTimeRatio = userTime/GCTime, 其中userTime表示用户程序运行时间,GCTime表示垃圾收集程序运营时间;