如何启用 java HotSpot VM 编译器

How to enable java HotSpot VM compiler

我正在使用 java 1.8.0_05、Java HotSpot(TM) 64 位服务器虚拟机 我是 运行 java 网络应用程序 tomcat 8.0.43

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

这导致记录了以下消息:

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= CodeCache: size=245760Kb used=244058Kb max_used=244079Kb free=1701Kb bounds [...] total_blobs=48344 nmethods=47669 adapters=584 compilation: disabled (not enough contiguous free space left)

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

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

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

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

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

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

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

会自动重启吗?

没有。它将一直保持关闭状态,直到 JVM 重新启动。

Can I simply restart tomcat?

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

There doesn't seem to be any noticeable different in how my application is running (eg: in terms of speed).

在较长的 运行 中,会出现一些问题,因为可以缓存和优化的代码无法再编译和存储在​​那里。

你能做什么?

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

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

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

编辑: 关于VisualVM,以下是连接远程JVM的官方步骤:

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

只需确保 JMX 已启用,它应该会立即运行。

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

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

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

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

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

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

  1. 安装 MBean JVisualVM 插件。
  2. 转到 Mbean
  3. 打开java.lang/MemoryPool/Code缓存
  4. 检查变量"Usage"(双击)

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

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

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

  • 我的应用程序与 运行ning 没有区别?

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

  • "I didn't get this message when deploying the same application"

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

  • 建议:

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