【问题标题】:How to enable java HotSpot VM compiler如何启用 java HotSpot VM 编译器
【发布时间】:2018-10-10 13:48:00
【问题描述】:

我正在使用 java 1.8.0_05,Java HotSpot(TM) 64 位服务器虚拟机 我在 tomcat 8.0.43 上运行一个 java web 应用程序

我最近部署了我的 .war 文件,方法是将其放到 webapps 文件夹中。

这导致记录以下消息:

Java HotSpot(TM) 64 位服务器虚拟机警告:CodeCache 已满。编译器 已被禁用。 Java HotSpot(TM) 64 位服务器虚拟机警告:尝试 使用 -XX:ReservedCodeCacheSize= 增加代码缓存大小 CodeCache: size=245760Kb used=244058Kb max_used=244079Kb free=1701Kb 界限 [...] total_blobs=48344 nmethods=47669 适配器=584 编译:禁用 (没有足够的连续可用空间)

如何检查编译器的当前状态,看看它是否仍然被禁用?

如何启用编译器?我可以简单地重启tomcat吗?

我的应用程序的运行方式似乎没有任何明显的不同(例如:在速度方面)。

有趣的是,将相同的应用程序部署到相同的服务器时,我没有收到此消息。这就是为什么我想首先重新打开编译器,而不是按照消息的建议更改设置(例如:ReservedCodeCacheSize)。

然后,如果问题仍然存在,我可以查看需要更改哪些设置。

【问题讨论】:

  • 对不起,我错过了你解释你已经将它部署在同一台服务器上的部分。你确定它们是一样的吗?您是否查看了代码缓存大小?也许用 VisualVM 监控两台服务器是个好主意。另外,要考虑到应用程序的使用会导致缓存加载。也许另一台服务器没有相同的负载?
  • 谢谢!如果应用程序在 Linux 服务器上运行,您是否有关于如何运行 VisualVM 的良好资源?我必须远程运行它吗?
  • 是的。我已经更详细地编辑了我的答案。
  • Update 5 已经很老了(4.5 年)。我会尝试更新 181。
  • 非常感谢。你认为这是造成问题的原因吗?会不会是我的代码做错了?因为据我了解,典型的应用程序不会遇到这个问题,而且我的应用程序也不是特别大......

标签: java tomcat jvm jit


【解决方案1】:

解决您的个人问题 + 1 条建议:

  • 如何检查 JIT 编译器是否仍然被禁用?

最简单的做法是启动一个 jvisualvm(JDK 已经提供),然后检查使用的代码缓存空间。如果您的 CodeCache 已满,JIT 编译器将保持禁用状态。检查代码缓存内存空间:

  1. 安装 MBeans JVisualVM 插件。
  2. 去Mbeans
  3. 打开 java.lang/MemoryPool/代码缓存
  4. 检查变量“Usage”(双击)

这将使您大致了解自己的位置。

  • 如何启用编译器?我可以简单地重新启动 tomcat 吗?

是的,重新启动肯定会重置缓存的状态。 重新启动编译器的唯一另一种方法是,如果您已经使用正确的参数启动了 JVM。 (启用UseCodeCacheFlushing

  • 我的应用程序运行方式没有区别?

JIT 会优化您的代码,但根据您的应用程序和您使用它的方式,您可能看不到任何明显的差异。假设您运行一个 web 应用程序(因为 Tomcat),网络传输速度或您的浏览器渲染页面可能比 JIT 在核心 Java 速度方面为您带来的速度要慢几个数量级。

  • “部署同一个应用程序时我没有收到此消息”

JIT 编译取决于当时正在执行的代码。 同一应用程序在 JIT 工作级别的底层运行可能完全不同。当涉及到低级函数时,您使用的第 3 方库越多,您就越无法确定在您无法控制的所有线程上发生了什么。

  • 建议:

请升级该 Java 版本。 JDK8 这么早的版本是非常罕见的(u_05),而且相当危险。 Java8 刚出来的时候并不是最稳定的版本,即使在以后的版本中也有容易重现的错误。 There have been over 1000 bugs 已在 JDK8 中修复。其中许多是直接解决 JIT 问题。如果您对正在与之交谈的环境有任何控制权,请升级它。如果您不这样做,请通知负责人。

【讨论】:

  • 谢谢! 1)我研究了监控但放弃了,因为它似乎涉及。我在linux上运行。你推荐远程运行 MBeans 吗?或者有没有办法在服务器上运行它? 2)在记录消息时,我部署了 3 个版本的应用程序(请参阅 Tomcat 自动部署),它们在一小时内取消部署)。这会导致问题吗? 3) 我的代码中是否存在导致问题的独特之处(例如:方法太多、公共静态变量太多等)? 4) 升级是个好主意,也是可能的。我会调查的!
  • 更正,我在上面(2)中提到的配置称为"parallel deployment"(不是autoDeploy)。
  • 1.如果启用 JMX,则可以远程连接到 JVM。通常很容易,除了一些网络问题。如果你幸运的话,这需要 2 分钟,你就准备好了。如果没有,只需发布​​一个 SO 问题并标记我。 2. 没有真正理解整个概念,抱歉。 3.我想不出任何可能导致过多JIT编译的“特殊代码”。 4.如果更新是一个选项,当然接受它,然后看看你的情况。我几乎可以肯定情况会改变。
【解决方案2】:

我前段时间遇到过这个问题,这是我不能告诉你的:

一旦代码缓存变满,编译器就会自动禁用。

会自动重启吗?

没有。它会一直保持下去,直到 JVM 重新启动。

我可以简单地重启tomcat吗?

是的。但它可能会再次发生。

我的应用程序的运行方式似乎没有任何明显的不同(例如:在速度方面)。

从长远来看,会出现一些问题,因为可以缓存和优化的代码不能再在那里编译和存储。

你能做什么?

  1. 你可以增加一点 -XX:ReservedCodeCacheSize
  2. 您可以启用 -XX:+UseCodeCacheFlushing。缺点是,如果您的 CodeCache 大小太小,并且您不断达到刷新阈值,则性能会受到影响,因为您在刷新过程中消耗了 CPU 资源。

我会增加一点 CodeCacheSize,启用刷新,并使用 VisualVM 或其他可以让您查看 CodeCache 的当前状态的东西来监控应用程序。监控将帮助您了解您是偶尔达到阈值还是经常发生。

请记住,CodeCache 与 Heap 是分开的,因此查看 HeapSize 对您没有帮助。

编辑: 关于 VisualVM,这里是连接到远程 JVM 的官方步骤:

https://docs.oracle.com/javase/8/docs/technotes/guides/visualvm/applications_remote.html

只要确保 JMX 已启用并且它应该可以立即工作。

关于同时运行许多应用程序的问题...嗯,是的,从技术上讲,标准 Tomcat 为所有应用程序启动一个 JVM。缓存空间将被共享。

您还可以通过将 VisualVM 附加到 JVM、取消部署应用并检查空间是否已释放来监控这种情况。

您还可以考虑使用 Enterprise 容器,它可以让您为每个应用创建一个 JVM。

【讨论】:

  • 谢谢! (1) 记录消息后,我部署了 3 个版本的应用程序(请参阅 tomcat autoDeploy。基本上,我部署新版本,而 tomcat 在一个小时内取消部署旧版本)。这是否会对 CodeCache 大小产生影响(即:负载是 3 倍,因为部署了 3 个应用程序)? (2) 我不认为我的 webapp 是独一无二的。据我了解,这个问题在正常情况下不应该出现。那么是不是我做了什么导致了这种情况(例如:许多方法、许多公共静态变量等)?
  • 更正:我在上面(1)中提到的配置称为"parallel deployment"(不是autoDeploy)
  • 是的。 Tomcat 默认启动单个 JVM 并共享 Code Cache 空间。
猜你喜欢
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-13
  • 1970-01-01
相关资源
最近更新 更多