java - Tomcat 的 Catalina 实用程序线程定期使用高 CPU 和内存

标签 java tomcat profiling heap-memory cpu-usage

我们有一个 Web 应用程序,在没有网络流量或任何类型的请求的情况下,空闲时平均使用 20% 的 CPU。 它在 Java 11、Tomcat 9、Spring Framework 5.3、Hibernate 5.4 上运行。 然而,我下面将描述的问题在 Java 8、Tomcat 8.5、Spring 4.3 和 Hibernate 4 上也同样存在。 我尝试使用 JFR 和 JMC 来分析应用程序,并尝试了很多配置。 enter image description here 在上图中,catalina-utility-1 和 catalina-utility-2 线程会定期唤醒,并在几秒钟内使用大量 CPU。 此外,这些线程似乎完成了大量的内存分配,在采样的 5 分钟间隔内总共分配了 30+ GB。

对于此分析,我已将 JFR 配置为最多记录所有内容,并启用所有选项。

enter image description here

当我尝试通过查看方法分析详细信息来更深入地了解细节时,我发现它似乎与 org.apache.catalina.webresources.Cache.getResource() 有关。 .

所以我开始阅读有关 Tomcat 缓存的内容,并尝试通过 context.xml 调整不同的参数。像这样的文件:

<Context>
  <!-- Default set of monitored resources. If one of these changes, the    -->
  <!-- web application will be reloaded.                                   -->
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
  <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
  <!-- Uncomment this to disable session persistence across Tomcat restarts -->
  <!--
    <Manager pathname="" />
    -->
  <Resources cachingAllowed="true" cacheMaxSize="3024000" cacheObjectMaxSize="10240" cacheTtl="10000"/>
</Context>

在这个用于 JFR 分析的特定示例中,我将缓存大小增加到 3GB 和 cacheTtl至 10 秒。我认为更大的缓存和更大的 TTL 会影响 CPU 峰值的间隔,因为我怀疑 Tomcat 默认每 5 秒检查一次缓存(最初大小为 1G)。 然而,无论我为缓存大小或 ttl 设置什么值,周期性 CPU 峰值都是相同的。 而且缓存大小足以容纳 Tomcat 想要放入其中的任何内容,因为在日志中看到警告后我增加了该值。无论如何,1GB 足以摆脱警告。

我还尝试了 1 到 5GB 的堆大小,上面的分析是使用 5GB 堆大小完成的。如果不开始达到物理内存限制,我就无法真正超过该值。

从 Java 8 天起,我们就使用 G1GC 作为垃圾收集器。调整其参数不会影响 CPU 使用率。 我也尝试了ParallelGC和SerialGC,但CPU使用模式没有变化。

在 Google 上搜索此类问题没有结果,我完全陷入了我还可以尝试什么或我还应该看什么的困境。

欢迎任何建议。谢谢。


更新1:

似乎我最初遇到了格式问题,并且开头 <context> context.xml 中缺少标签当解析时。已修复。

我也尝试过,按照 <Context reloadable="false"> 的建议以便可重新加载显式设置为 false。完全没有效果。

是否可以从其他地方设置可重新加载标志?我猜测即使在 context.xml 中,也许其他文件或设置也应用了它。它设置为 false .

最佳答案

图像中的堆栈跟踪包含对 Loader#modified 的调用仅当您将上下文的 reloadable 属性设置为 true 时才可能实现:

<Context reloadable="true">
...
</Context>

Tomcat's documentation 中所述:

Set to true if you want Catalina to monitor classes in /WEB-INF/classes/ and /WEB-INF/lib for changes, and automatically reload the web application if a change is detected. This feature is very useful during application development, but it requires significant runtime overhead and is not recommended for use on deployed production applications. That's why the default setting for this attribute is false.

(强调我的)。

reloadable设置为false(或删除该属性)以消除开销。

关于java - Tomcat 的 Catalina 实用程序线程定期使用高 CPU 和内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68812689/

相关文章:

java - 使用 cargo maven 插件将 spring 项目部署到远程服务器

spring - 运行时出错 : java. lang.ClassNotFoundException : org. springframework.web.context.ContextLoaderListener

tomcat - 如何在端口 80 上运行 nexus sonatype?

c++ - 如何编写一个简单的代码分析器?

java - Kotlin 类属性和 Java 类字段有什么区别

java - 一些最近更改的资源尚未发布

java - 哪个更快,或者它只是被认为是错误的代码

java - 为什么 date.toString() 两次打印相同的结果

java - Google 应用程序引擎分析器

c++ - Linux C++ : how to profile time wasted due to cache misses?