什么是ReservedCodeCacheSize和InitialCodeCacheSize?

95
有人能解释一下JVM选项ReservedCodeCacheSize和InitialCodeCacheSize是什么吗?具体来说,我何时/为什么想要更改它?我如何决定正确的大小?
文档中的示例:
-XX:ReservedCodeCacheSize = 32m 保留的代码缓存大小(以字节为单位) - 最大代码缓存大小。[Solaris 64位,amd64和-server x86:2048m;在1.5.0_06及更早版本中,Solaris 64位和and64:1024m]

2
这篇帖子的OP写道:>-XX:ReservedCodeCacheSize=32m 保留代码缓存大小(以字节为单位)-最大代码缓存大小。[Solaris 64位,amd64和-server x86:48m;在1.5.0_06及更早版本中,Solaris 64位和and64:1024m。]我只想纠正一下48m的上限是笔误。它应该是2048m。 - Lasse Aagren
4个回答

80

ReservedCodeCacheSize(以及 InitialCodeCacheSize)是Java Hotspot VM的(即时)编译器选项。基本上,它设置了编译器代码缓存的最大大小。

缓存可能会变满,导致出现以下警告:

Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
Java HotSpot(TM) 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=
Code Cache  [0x000000010958f000, 0x000000010c52f000, 0x000000010c58f000)
 total_blobs=15406 nmethods=14989 adapters=362 free_code_cache=835Kb largest_free_block=449792

当出现Java HotSpot(TM)客户端VM警告:分派信号SIGINT到处理程序时发生异常java.lang.OutOfMemoryError- VM可能需要被强制终止时情况会更糟。

何时设置此选项?

  1. 在拥有Hotspot编译器故障时
  2. 为减少JVM所需的内存(因此冒着JIT编译器故障的风险)

通常情况下不需要更改此值。我认为默认值已经很好地平衡了,因为这种问题很少出现(根据我的经验)。


1
好的。默认值是什么,如果我们看到“CodeCache已满”的警告,应该将它们增加到多少? - axel22
3
实际上,这些值取决于平台和JVM版本;来自Sun JVM文档的值:保留代码缓存大小(以字节为单位)-最大代码缓存大小。[Solaris 64位,amd64和-server x86:48m;在1.5.0_06及更早版本中,Solaris 64位和amd64:1024m。]不知道OpenJDK的值。适度增加应该就足够了(之前设定的1024m已经足够好了)。 - jeha

14

@jeha回答了我这个问题中想知道的所有内容,除了参数应该设置成什么值。由于我没有编写正在部署的代码,因此对其占用内存的情况不太清楚。

但是,您可以使用jconsole附加到运行中的java进程,然后使用“Memory”选项卡找出“Code Cache”大小。为了完整起见,以下是步骤(Linux VM环境,尽管我相信其他环境也类似):

  1. 在您的机器上启动jconsole
  2. 找到正确的进程ID并将jconsole附加到它上面(这将需要一些时间)
  3. 导航到“Memory”选项卡
  4. 从“Chart:”下拉列表中选择“Memory Pool“Code Cache””
  5. 同样,这可能需要一些时间来刷新屏幕,然后您应该看到如下所示的内容: jconsole code cache image

    正如您所看到的,我的代码缓存使用了大约49 MB。此时,我仍然使用默认值,即文档(和@jeha)表示为48 MB。这无疑是我增加设置的一个很好的动力!

    Ben.


    默认情况下1024 MB可能有点过度,但默认情况下48 MB似乎不够用...


好的建议...我正在尝试使用-J-XX:ReservedCodeCacheSize=512m。 - MarcoZen
Netbeans无法使用512m启动,但可以使用256m启动。 - MarcoZen
经过大约2天的测试,我可以说这项设置没有显示出任何/任何明显的改进,反而让NetBeans变得不稳定。最终我只好将其移除。 - MarcoZen

3

Indeed工程团队迁移到jdk 8时所面临的挑战及其良好的学习经验。

http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/

结论: Jdk 8需要比JDK 7更多的代码缓存。

JRE 8的默认代码缓存大小约为250MB,是JRE 7默认值48MB的五倍左右。我们的经验表明,JRE 8确实需要额外的代码缓存。到目前为止,我们已经将大约十项服务迁移到了JRE 8,并且所有这些服务使用的代码缓存量比之前多了四倍左右。


0

来自https://blogs.oracle.com/poonam/entry/why_do_i_get_message

以下是关于CodeCache清除的jdk7u4+中已知的两个问题:

  1. 即使在紧急刷新后,CodeCache占用率下降到接近一半,编译器可能仍不会重新启动。
  2. 紧急刷新可能导致编译器线程的高CPU使用率,从而导致整体性能下降。

JDK8已经解决了这个性能问题和编译器不能再次启用的问题。为了解决JDK7u4+中的这些问题,我们可以使用ReservedCodeCacheSize选项增加代码缓存大小,将其设置为大于已编译代码的占用空间,以便CodeCache从未变满。另一个解决方案是使用-XX:-UseCodeCacheFlushing JVM选项禁用CodeCache Flushing。

上述问题在JDK8及其更新版本中已经得到了解决。

因此,在运行JDK 6(已禁用代码刷新)和7的系统上提及此信息可能值得一提。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接