我使用jstack输出线程信息。有一个线程:"VM Thread" prio=10 tid=0x0878b400 nid=0x760a runnable。
这个线程是用来做什么的? 它占用了50%的CPU使用率和大部分CPU时间。
我使用jstack输出线程信息。有一个线程:"VM Thread" prio=10 tid=0x0878b400 nid=0x760a runnable。
这个线程是用来做什么的? 它占用了50%的CPU使用率和大部分CPU时间。
我认为这是垃圾回收线程。它执行垃圾回收。
VM线程是JVM的内部线程,您在JConsole中看不到它,但可以在threaddump
(使用jstack
)或操作系统实用程序(例如top(top -H ....)
或ps
)中看到。
如果此VM线程始终占用大量CPU,则可能是OOM堆错误的前兆。
通常情况下,这可能是由于“停止世界”GC发生而导致的。这可能是由于内存泄漏,也可能是由于在单个CPU和/或串行GC收集器上运行和/或将堆加载到无法进行GC的对象(因为它们在堆栈上处于活动状态)和/或将堆大小调整得太低与工作流和隐含并发性等。
以下是示例。
复制很简单:
尝试在受限堆上运行(例如256m),使用docker或特定于操作系统的实用程序限制到单个CPU,指定更多的工作线程读取图像到内存中,您将看到使用此命令(在Linux上):
top -n 1 -H -p {pid}
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10 root 20 0 3335964 395380 28380 R 60.0 19.4 0:34.71 VM Thread
你怎么知道这个线程占用了50%的CPU?可运行并不意味着它在消耗CPU。
据我所知,这是用于内部Java操作的,可能涉及GC。
你使用的Java版本是哪个?我建议检查你是否有最新版本的Java,并查看是否仍然存在此问题。
我建议你对应用程序进行内存分析,以查看你创建了多少对象,并尝试减少对象数量以减轻任何GC工作负载。