我们刚刚开会解决了用于计算保险费率的Web应用程序中的一些性能问题。计算是在C / C 模块中实现的,该模块也可在其他软件包中使用。为了使其可作为Web服务使用,实现了Java包装器,该包装器公开了基于XML的接口并通过JNI调用C / C 模块。
测量表明,Java部件内部的每次计算花费了几秒钟。因此,我的第一个建议是在VM中启用垃圾收集日志记录。我们可以立刻看到很多停产的完整GC。谈到这一点,java部分的开发人员告诉我们,他们曾System.gc()多次“确保使用后释放内存”。
System.gc()
好的,我不再赘述… ;-)
然后,我们也添加了上述-XX:+DisableExplicitGCVMs参数,然后重新运行测试。每次计算大约增加了5秒。
-XX:+DisableExplicitGC
由于我们无法System.gc()在发布过程中通过剥离所有这些调用来更改代码,因此我们正在考虑增加-XX:+DisableExplicitGC生产,直到可以创建新的Jar。
现在的问题是:这样做会有任何风险吗?我唯一能想到的是tomcat System.gc()在重新部署时在内部使用,但这只是一个猜测。前方还有其他危险吗?
通过设置-XX:+DisableExplicitGC标志来修复世界各地的GC事件的人并不孤单。不幸的是(尽管有文档中的免责声明),许多开发人员认为他们在何时收集内存并确切介绍此类问题时比JVM更了解。
我知道许多情况下-XX:+DisableExplicitGC生产环境得到了改善,零例情况下有任何负面影响。
安全的做法是在负载下运行当前的生产代码,并在压力测试环境中设置该标志并执行正常的质量检查周期。
如果您不能这样做,我建议在大多数情况下,设置标志的风险要比不设置标志的成本低。