快速,低成本,低扰动地运行一段Java代码

栏目: Java · 发布时间: 7年前

内容简介:JVM是个运行服务端应用的好VM,但如果你只是想频繁地运行一段Java写的脚本,或者在跑一些辅助性的Java程序比如监控,比如日志收集,这时候的诉求就和平日里的应用不一样了:一、启动快速,动静小。二、低成本,节约CPU、内存和线程。

JVM是个运行服务端应用的好VM,但如果你只是想频繁地运行一段 Java 写的脚本,或者在跑一些辅助性的Java程序比如监控,比如日志收集,这时候的诉求就和平日里的应用不一样了:

一、启动快速,动静小。

二、低成本,节约CPU、内存和线程。

三、低扰动,不干扰主应用的运行。

1. 从失败的取经开始

第一时间,看看jmap,jstack们用了什么参数,结果发现通通只有一个-Xms8m (在它们运行时,跑jps -v 可见,源码级确认JDK7见Makefile.launcher,JDK8见CompileLaunchers.gmk)。

另外,传说中的-client,在多核的 Linux 服务器上的也是无效的。

下面开始自己的折腾,首先给跑的脚本配上"-Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime", 在gc.log 里就会有实际启动参数,GC日志,以及结束时打印内存各代的占用。

其次,长期跑一个 pidstat -l 1| grep XXX 监控进程的CPU消耗

最后,jstack一下进程,看看里面跑着多少线程,一个默认的JVM,线程数多得吓人。

2. 类的加载和编译

2.1 -Xverify:none

来自优化Eclipse启动速度的经验,说关闭Java类加载验证可以加快10% -15%的启动速度。

2.2 设定编译级别

JIT编译之后的代码比解释执行字节码更快,更省CPU,但编译本身就需要CPU,也需要额外的编译线程。临时给启动脚本配上 “-XX:+PrintCompilation”,观察编译情况。

如果脚本的代码只简单的跑一次,比如vjtools里的vjmxcli,建议就不要进行JIT编译了,编译完了也用不上,直接解释执行就好。禁止它:-Djava.compiler=NONE

如果脚本会用于循环计算,比如vjtools里的vjmap,则建议打开多层编译,一开始就对运行到的方法进行静态编译,不用等方法被调用1万次。多层编译在JDK8默认打开,显式打开:-XX:+TieredCompilation。

但打开多层编译也会导致程序运行初期有较多的编译任务,吃比较多的CPU,可以显式关掉多层编译 -XX:-TieredCompilation来对比一下,综合其带来的性能提升,脚本的生命周期长短,以及额外的CPU支出来综合评价。

2.3 编译线程的设定

在24核服务器上,默认有4条C1编译线程,8条C2编译线程(多层编译下),考虑到低成本原则,建议把它设到最小的-XX:CICompilerCount=2。

2.4 未来黑科技-AOT

JIT不够酷,预先把代码编译(Ahead-of-Time,AOT) 更好。 JDK9里有一个Hotspot编译器组搞的试验性的jaotc,另一个选择是GraalVM全家桶里带的 SubstrateVM ,这个支持JDK8。两者都是基于Graal,看各位大大炫,但我还没玩过。

3. GC 设置

这些脚本,辅助进程一般不介意GC延时,建议使用吞度量最的串行收集算法 -XX:+UseSerialGC,大大减少了其他GC算法所产生的大量GC线程,保证自己GC时也不会影响到主应用。

如果依然想使用并行算法,就一定要设置GC线程数,如果按默认值,在24核机器上YGC和CMS GC的线程数分别是18和5,一旦发生GC,将占用大量的CPU核,直接对主应用产生巨大的影响。可设为 -XX 快速,低成本,低扰动地运行一段Java代码 arallelGCThreads=2 -XX:ConcGCThreads=1

4. 内存设置

JVM的堆内存扩张并没有想象中那么智能,当-Xms 与 -Xmx 不等,又没有指定新生代比例时,新生代大小更是混乱。建议根据运行后的实际占用及GC日志,完整设置一个最合适的值。

快速运行一次的脚本,老生代几乎没用,新生代可以设大些。

-Xms96m -Xmx96m -Xmn64m

长期运行的,则一般设为1:1。

-Xms256m -Xmx256m -XX:NewRatio=1

每条线程的内存从默认1M回到256k: -xss256k

永久代也可以一设,可惜JDK7/8的参数不兼容,用java -version 拿版本号太贵了,所以如果明确了JDK版本的话可以设置,否则就算了。

5. 其他

这些脚本,免不了和数字打交道,如果不保证没有int ->Integer的autoboxing,就还是打开-XX:AutoBoxCacheMax=20000

如果有其他更多黑科技,请大家补充。

6. 小结

谢谢你看到这里,这篇的题材比较偏门,幽僻处可有人行。

一段快速执行,关闭了JIT的脚本,启动命令大概长这个样子:

-Xms96m -Xmx96m -Xmn64m -Xss256k -XX:+UseSerialGC -Djava.compiler=NONE -Xverify:none -XX:AutoBoxCacheMax=20000

一段辅助程序,启动命令大概长这个样子

-Xms256m -Xmx256m -XX:NewRatio=1 -Xss256k -XX:+UseSerialGC -XX:-TieredCompilation -XX:CICompilerCount=2 -Xverify:none -XX:AutoBoxCacheMax=20000

VJTools 几个 工具 的启动脚本,都按这个标准重写了一下。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

众包

众包

杰夫·豪 / 牛文静 / 中信出版社 / 2009-6 / 36.00元

本书是继《长尾理论》之后的重要商业书籍。本书回答了《长尾理论》遗留的一大悬念。在长尾中作者详细阐述了长尾之所以成为可能的一个基础,但是没有详细解读,本书就是对这一悬念的详细回答,是《长尾理论》作者强力推荐的图书,在国际上引起了不小的轰动,“众包”这一概念也成为一个标准术语被商界广泛重视。本书大致分为三个部分,介绍众包的现在、过去和未来,解释了它的缘起、普遍性、力量以及商业上的适用性,通俗易懂,精彩......一起来看看 《众包》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具