繁体   English   中英

JVM编译时间与代码缓存

[英]JVM Compile Time vs Code Cache

我一直在对我的应用程序进行基准测试并使用JMC进行分析。 我注意到在负载下,它执行了相当多的JIT编译。 如果我每秒发送大量事务,则编译时间会激增。 编译时间总是与针对应用程序的任何重负载测试成比例增长。

我还观察到代码缓存也慢慢上升。 所以我决定将代码缓存保留提高到500MB进行测试。 不好动! 现在它花费更多时间执行JIT。

然后我通过-XX:-UseCodeCacheFlushing显式禁用了代码缓存刷新。 但是,我注意到代码缓存的峰值使用率大于当前大小。 这引出了几个问题:

在此输入图像描述

  1. JVM是否尝试缓存每个JIT编译?
  2. 为什么即使禁用了刷新,峰值代码缓存大小也会大于当前大小?
  3. 是否有“临时”编译代码在函数结束后自动删除?

在HotSpot JVM中,所有JIT编译的方法都保留在CodeCache中,直到它们被回收为止。 UseCodeCacheFlushing影响冷(但仍然有效)编译方法的回收。 但是,CodeCache还可能包含过时或无效的方法(“僵尸”),即使使用-XX:-UseCodeCacheFlushing ,这些方法也会在下一个扫描周期进行清除。

  • 分层编译模式中(默认自JDK 8),可以使用不同级别的优化来编译多次方法。 一旦安装了方法的优化(第4层)版本,之前的版本就会过时,并且可以在完成该版本的所有激活后回收。
  • 当推测失败时(例如,在加载新类之后),推测编译的方法可能变得无效。 这种方法也变成僵尸,以后可以回收。
  • 另一个例子是OSR编译 这是一个专门编译的方法版本,用于在方法运行时将执行从解释器转移到编译代码。 回答第3个问题,这是一种“临时”方法,在安装完整版本的编译方法并完成所有OSR激活后,该方法就会过时。

有一个单独的JVM标志-XX:-MethodFlushing来防止彻底扫描CodeCache,包括僵尸方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM