【问题标题】:jvm - About code cache areajvm - 关于代码缓存区
【发布时间】:2016-03-07 10:12:56
【问题描述】:

这是关于JVM中缓存区的一些问题:(for hotspot Java8

  • jvm可以运行的机器码是全部都存放在这个区域,还是只有一些热代码存放在这里?
  • 从某本书中可以看出,客户端编译器 (C1) 更有可能耗尽缓存区的内存,而服务器编译器 (C2) 则不会。我对此有点困惑。那是因为服务器编译器只编译热部分,而中断另一部分吗?那么,服务器编译器不应该很慢吗?
  • 代码在 C1 和 C2 分别编译和缓存之前运行了多少次?

【问题讨论】:

  • 顺便说一句,如果您对性能感兴趣,this book 可以很好地概述它的许多方面。
  • @biziclop 不错的建议,谢谢。

标签: java jvm jit


【解决方案1】:

请注意,这个问题的答案可能因实施而异:

jvm 可以运行的所有机器代码是否都存储在该区域中,或者仅 这里存储了一些热代码?

代码缓存几乎总是用于缓存热方法(或曾经被 C1 + C2 视为的方法(分层编译 )

从某本书中,它说客户端编译器 (C1) 更有可能用完 缓存区域中的内存,而服务器编译器(C2)没有。我是一个 对此有点困惑。那是因为服务器编译器只有 编译热的部分,打断另一部分?在这种情况下, 服务器编译器不应该很慢吗?

C1 编译器编译所有内容。 C2 一直等到它找到一些可以应用的优化,然后应用这些优化并编译方法(并非总是如此,但大多数情况下)。

注意C1可以多次编译同一个方法。

代码在 C1 和 C2 编译之前运行了多少次 分别?

如果 C1 / C2 发现运行时间较长,即使只调用一次方法也可以编译。

您可以使用 JITWatch 查看 C1 和 C2 的运行情况。

【讨论】:

  • 谢谢,但第一个问题的答案对我来说有点模糊,我主要关注java8热点,你能在此基础上更清楚吗?
  • A method can be compiled even if it is called only once if C1 / C2 find out that it is taking a long time to run. 不是直接的,而是每个循环都有一个分支计数,它告诉 Hotspot 循环完成了多少次迭代。如果该计数器达到阈值,则编译循环本身,即使方法本身仍在运行。
  • @biziclop 关于第一个问题,在使用c1的时候,如果一个方法只运行一次并且对jvm来说很快,那么这个方法还是会被编译的,对吧?而且还会缓存在代码缓存区吗?
  • @EricWang 否。默认编译阈值是 C1 的 1500 和 C2 的 10000(或类似的东西)。如果组合的分支 + 调用计数超过该阈值,则该方法被声明为热并被编译。但是计数也会定期减少,因此如果调用间隔相当均匀,即使在应用程序的生命周期内被调用一百万次的方法也可能不会被编译,
  • @biziclop 阈值 1500 和 10000 在分层编译中没有太大作用(JDK 8 中的默认值)。编译策略要复杂得多,请参阅this answer
猜你喜欢
  • 1970-01-01
  • 2014-11-19
  • 2010-12-31
  • 2010-12-07
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多