我正在运行Oracle Java 8 JVM(服务器,而不是客户端或嵌入式),启用了ReservedCodeCacheSize = 128M和UseCodeCacheFlushing。几天之后,Codecache迅速从93%降至80%。我假设我目睹了一个Codecache同花顺,但令人惊讶的是,后冲洗大小接近100%满,而不是50%满。
JVM如何决定要刷新多少Codecache?
This Oracle Java 8 page描述了该选项,但没有量化刷新的Codecache:
在关闭编译器之前启用刷新代码缓存。默认情况下启用此选项。要在关闭编译器之前禁用刷新代码缓存,请指定-XX:-UseCodeCacheFlushing。
有一个JVM选项UseCodeCacheFlushing可用于控制Codecache的刷新。启用此选项后,JVM将调用紧急刷新,丢弃旧版本的一半编译代码(nmethods),以便在CodeCache中提供空间。
可以想象,编译代码的旧版本只占整个Codecache的20%,但另一种可能的解释是上述博客文章不准确。
答案 0 :(得分:5)
'较旧的一半'并不意味着所有nmethods的50%。用于扫描编译代码的HotSpot逻辑有点复杂;最好的解释是source code,但我将在下面给出一个简短的摘要。
如果满足以下条件中的至少一个,则调用sweeper:
ReservedCodeCacheSize
的1%)。当清扫程序运行时,它总是释放所有 zombie nmethods,即没有激活的卸载,去优化或重新编译的方法。
此外,如果启用了UseCodeCacheFlushing
,它会释放 cold cold 的nmethods。冷方法确定如下:
2 * (ReservedCodeCacheSize / 1MB)
。-XX:NmethodSweepActivity
选项(默认为10)。较大的是NmethodSweepActivity
,代码缓存自由比率越小,编译的方法就越苛刻。 Here就是公式。因此,没有确切的数字可以编写多少编译方法。这是在运行时计算的,具体取决于保留的代码缓存大小,可用空间量,僵尸方法的数量,冷方法的数量以及NmethodSweepActivity
等JIT人体工程学选项。