什么是ReservedCodeCacheSize和InitialCodeCacheSize?
有人可以请解释什么JVM选项ReservedCodeCacheSize
和InitialCodeCacheSize
是什么? 具体何时/为什么要改变它? 我如何确定合适的尺寸是多less?
这是文档所说的:
-XX:ReservedCodeCacheSize = 32m预留代码caching大小(以字节为单位) – 最大代码caching大小。 [Solaris 64位,amd64和-server x86:2048m; 在1.5.0_06及更早版本中,Solaris 64位和64位:1024m。]
ReservedCodeCacheSize
(和InitialCodeCacheSize
)是Java Hotspot VM(即时编译器)的选项。 基本上它为编译器的代码caching设置了最大的大小。
caching可能会变满,导致如下警告:
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) Client VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated
时,情况会更糟糕Java HotSpot(TM) Client VM warning: Exception java.lang.OutOfMemoryError occurred dispatching signal SIGINT to handler- the VM may need to be forcibly terminated
。
何时设置此选项?
- 当有热点编译器失败时
- 以减lessJVM所需的内存(并因此导致JIT编译器失败的风险)
通常你不会改变这个值。 我认为默认值是很好的平衡,因为这个问题发生在非常罕见的场合(在我的经验)。
@jeha回答了我想从这个问题中知道的一切,除了设置参数的值。 由于我没有写代码,所以我没有太多的内存占用的可见性。
但是,您可以使用jconsole附加到正在运行的java进程,然后使用“Memory”选项卡查找代码caching大小。 为了完整,步骤是(Linux VM环境,但我确定其他环境是相似的):
- 在你的机器上启动jconsole
- find正确的进程ID,并附上jconsole(这将需要一些时间)
- 导航到“内存”选项卡
- 从“Chart:”下拉列表中select“Memory Pool”Code Cache“”
-
同样,屏幕刷新可能需要一些时间,然后您应该看到如下所示的内容:
正如你所看到的,我的代码caching使用大约49 MB。 在这一点上,我仍然有默认文件(和@jeha)说是48 MB。 当然是我增加设置的一个很大的动力!
本。
默认情况下,1024 MB可能是过度使用它,但默认情况下,48 MB似乎在进行中…
当JVM编译代码时,它将在代码高速caching中保存一组汇编语言指令。 代码caching具有固定的大小,一旦填充完成,JVM将无法编译任何其他代码。
代码caching的最大尺寸是通过-XX:ReservedCodeCacheSize = N标志(其中N是为特定编译器提供的默认值)设置的。 代码caching像JVM中的大部分内存一样被pipe理:有一个初始大小(-XX:InitialCodeCacheSize = N)。 代码caching大小的分配从初始大小开始,随着caching填满而增加。 代码caching的初始大小根据所使用的芯片架构和编译器而有所不同。 调整caching大小发生在后台,并不会真正影响性能,因此设置ReservedCodeCacheSize大小(即设置最大代码caching大小)是通常所需的。
默认情况下,对于64位服务器,Java 7的大小是48 MB(分层编译为96 MB)。 在Java 8 for 64位服务器中,内存大小为240 MB。
Pinaki
来自Indeed工程团队的良好学习经验以及他们在向jdk迁移时所面临的挑战8。
http://engineering.indeedblog.com/blog/2016/09/job-search-web-app-java-8-migration/
结论:在JDK 7中,Jdk 8需要更多的代码caching
JRE 8的默认codecache大小约为250MB,比JRE 7的48MB默认大约大5倍。我们的经验是JRE 8需要额外的编码caching。 到目前为止,我们已经将大约十个服务转换到了JRE 8,并且所有这些服务比以前多用了大约四倍的代码caching。
从https://blogs.oracle.com/poonam/entry/why_do_i_get_message :
以下是jdk7u4 +中关于CodeCache刷新的两个已知问题:
- 即使在紧急刷新后,CodeCache占用率下降到接近一半,编译器也可能无法重新启动。
- 紧急刷新可能会导致编译器线程的CPU使用率过高,导致整体性能下降。
JDK8解决了这个性能问题,以及编译器不能重新启用的问题。 要在JDK7u4 +中解决这些问题,我们可以使用ReservedCodeCacheSize选项来增加代码caching大小,将其设置为比编译代码足迹大的值,这样CodeCache永远不会变满。 解决此问题的另一个方法是使用-XX:-UseCodeCacheFlush JVM选项禁用CodeCache刷新。
上述问题已经在JDK8及其更新中得到解决。
因此,对于在JDK 6上运行的系统(禁用代码清除)和7,这些信息可能值得一提。