在JVM上启用了逃逸分析的经验

我刚刚尝试在jdk6-u18 VM(在solaris上)启用了-XX:+DoEscapeAnalysis选项,并且遇到了相当令人失望的经历。 我正在运行一个scala应用程序,它有很多演员(其中有20,000个)。 这是垃圾创建的秘诀!

通常,应用程序可以使用256Mb的堆运行,但会产生大量垃圾。 在稳定状态下:

  • 在GC中花费10%的时间
  • 在 150Mb的垃圾然后获得GC

我认为转义分析可能会有所帮助,所以我启用了该选项并重新运行了应用程序。 我发现应用程序变得越来越无法清除它收集的垃圾,直到它似乎最终花费了整个时间来做GC并且应用程序在其完全分配时“扁平化”。

在这一点上,我应该说应用程序没有抛出我所期望的OutOfMemoryError 。 也许JConsole (我用来执行分析)没有正确显示带有此选项的GC统计数据(我不相信)?

然后我删除了该选项并重新启动,应用程序再次变为“正常”! 任何人都知道可能会发生什么?

1转义分析是否显示为在JConsole中启用? 您需要确保使用-server选项运行VM。 我假设你有这个工作,但我只是想我会检查。

2我不认为逃逸分析会对Scala Actors的情况有所帮助。 如果您执行以下操作,您可能会看到很大的收获:

 def act():Unit = { val omgHugeObject = new OMGHugeObject(); omgHugeObject.doSomethingCrazy(); } 

在上面的例子中,EscapeAnalysis会使它如此omgHugeObject可以在堆栈而不是堆上分配,因此不会产生垃圾。 我认为逃脱分析不太可能对演员有所帮助。 他们的引用总是“逃避”到actor子系统。

3您是否在Scala的最新版本中? 有一个内存泄漏,我相信在最近的版本中修复了。 这甚至导致Lift产生了你可能会查看的自己的Actor库。

4您可以尝试G1Garbage收集器您可以使用以下命令启用它:

-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC

来自jdk-u18发行说明 :

请注意,在6u18中禁用基于Escape分析的优化(-XX:+ DoEscapeAnalysis)。 此选项将在将来的Java SE 6更新中恢复。

我建议你尝试增加新一代的尺寸,例如-XX:NewSize=96M XX:NewRatio=3 。 使用JVisualVM(包含在JDK中)和Visual GC插件来观察年轻和旧空间的使用方式。