「字节跳动」厉害!代表Java未来的ZGC深度剖析( 四 )


下面对部分参数进行更加详细的说明 。

  • UseNUMA
ZGC默认是开启支持NUMA的 , 不过 , 如果JVM探测到系统绑定的是CPU子集 , 就会自动禁用NUMA 。 我们可以通过参数-XX:+UseNUMA显示启动 , 或者通过参数-XX:-UseNUMA显示禁用 。 如果运行在NUMA服务器上 , 并且设置-XX:+UseNUMA , 那对性能提升是显而易见的 。
  • UseLargePages
配置ZGC使用large page通常就会得到更好的性能 , 比如在吞吐量、延迟、启动时间等方面 。 而且没有明显的缺点 , 除了配置过程复杂一点 。 因为它需要root权限 , 这也是默认并没有开启使用large page的原因 。
  • ConcGCThreads
ZGC是一个并发垃圾收集器 , 那么并发GC线程数就非常重要了 。 如果设置并发GC线程数越多 , 意味着应用线程数就会越少 , 这肯定是非常不利于应用系统稳定运行的 。 这个参数ZGC能自动设置 , 如果没有十足的把握 。 最好不要设置这个参数 。
  • ParallelGCThreads
这是个并行线程数 , 与上一个参数ConcGCThreads有所不同 , ConcGCThreads表示GC线程和应用线程「并发」执行时GC线程数量 。 而ParallelGCThreads表示GC时STW阶段的「并行」GC线程数量(例如第一阶段的Root扫描) , 这时候只有GC线程 , 没有应用线程 。 笔者这里解释了JVM中「并发和并行的区别」 , 也是JVM中比较容易理解错误的地方 。
  • ZUncommit
掌握这个参数之前 , 我们先说一下JVM申请以及回收内存的行为 。 以前的垃圾回收器比如ParallelOldGC和CMS , 只要JVM申请过的内存 , 即使发生了GC回收了很多内存空间 , JVM也不会把这些内存归还给操作系统 。 这就会导致top命令中看到的RSS值会越来越高 , 而且一般都会超过Xmx的值(参考文章:) 。
不过 , 默认情况下 , ZGC是会把不再使用的内存归还给操作系统的 。 这对于那些比较注意内存占用情况的应用和服务器来说 , 是很有用的 。 这种行为可以通过JVM参数**-XX:-ZUncommit**关闭 。 不过 , 无论怎么归还 , JVM至少会保留Xms参数指定的内存大小 , 这就是说 , 当Xmx和Xms一样大的时候 , 这个参数就不起作用了 。
和这个参数一起起作用的还有另一个参数:-「XX:ZUncommitDelay=sec」 , 默认300秒 。 这个参数表示不再使用的内存最多延迟多长时间才会被归还给操作系统 。 因为不再使用的内存不应该立即归还给操作系统 , 这样会造成频繁的归还和申请行为 , 所以通过这个参数来控制不再使用的内存需要经过多久的时间才归还给操作系统 。
Change Log接下来 , 我们看一下从JDK11到JDK15这5个版本 , ZGC都迭代了哪些特性:
JDK 15 (under development)
  • Improved NUMA awareness
  • Support for Class Data Sharing (CDS)
  • Support for placing the heap on NVRAM
JDK 14