Java vm 速度变慢,所有线程都忙于字符串操作

2022-09-01 21:15:19

我遇到了一个非常奇特的问题。我的tomcat在大约25%的CPU 24/7下完美运行,但有时我的CPU高达60%,系统停止运行,无法恢复。

当我在减速期间进行线程转储时,几乎所有线程都忙于某种字符串或相关操作。

没有OutOfMemory错误或抛出任何异常,所有请求仍然被处理,但响应时间恶化到第n个程度,即使是亚秒级请求也会减慢到60秒甚至更长时间。

我的服务器配置如下:

    Ubuntu 12.04.2 LTS
    Linux 3.2.0-38-virtual #60-Ubuntu SMP x86_64 x86_64 x86_64 GNU/Linux
    java version "1.7.0_13"
    Java(TM) SE Runtime Environment (build 1.7.0_13-b20)
    Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
    export JAVA_OPTS='-server
    -Xms18g -Xmx18g
    -XX:MaxPermSize=512m
    -XX:ThreadStackSize=512
    -XX:NewRatio=1
    -XX:SurvivorRatio=4
    -XX:+UseConcMarkSweepGC
    -XX:+UseParNewGC
    -XX:+CMSClassUnloadingEnabled
    -Xloggc:/usr/tomcat/logs/gc.log
    -XX:+PrintGCDetails
    -XX:+PrintGCDateStamps
    -XX:+PrintTenuringDistribution
    -Dcom.sun.management.jmxremote
    -Dcom.sun.management.jmxremote.port=9999
    -Dcom.sun.management.jmxremote.authenticate=false
    -Dcom.sun.management.jmxremote.ssl=false
    -Djava.awt.headless=true'

单击此处下载线程转储。我已经删除了大部分线程及其堆栈跟踪

单击此处下载 vmstat 日志

点击这里下载gc日志

关于原因的任何想法?谢谢


答案 1

尝试使用以下 JVM 选项增加代码缓存的最大大小:

-XX:ReservedCodeCacheSize=256m

请参阅我对另一个问题的回答,了解此建议的背景。


答案 2

要尝试查明有问题的请求,您可以在Tomcat中配置卡住的线程检测阀

此阀允许检测需要很长时间才能处理的请求,这可能表示正在处理它的线程已卡住。

当检测到这样的请求时,其线程的当前堆栈跟踪将写入具有WARN级别的Tomcat日志。

卡住线程的 ID 和名称可通过 JMX 在 stuckThreadIds 和 stuckThreadNames 属性中获得。这些 ID 可以与标准的 Threading JVM MBean (java.lang:type=Threading) 一起使用,以检索有关每个卡住的线程的其他信息。


推荐