JVisualVM 监控线程池状态
JVisualVM 可以用来监控 Java 线程池(ThreadPoolExecutor) 的状态,包括线程数、CPU 使用率、任务执行情况等。以下是详细的监控步骤:
一、启动 JVisualVM
- 打开 JVisualVM 
  - 如果是 JDK 8 及以下,JVisualVM 自带,可以直接在 JDK 的 bin目录下找到jvisualvm.exe并运行。
- 如果是 JDK 9 及以上,需要单独下载安装:https://visualvm.github.io/
 
- 如果是 JDK 8 及以下,JVisualVM 自带,可以直接在 JDK 的 
- 连接目标 Java 应用 
  - 启动你的 Java 应用(确保 JMX 远程管理开启)。
- 在 JVisualVM 左侧的「本地」或「远程」列表中,找到你的 Java 进程,并双击连接。
 
二、监控线程池状态
1. 在 “监视” (Monitor) 选项卡
- CPU 使用率:观察 CPU 利用率,是否因线程池配置不当导致资源浪费或不足。
- 堆内存使用:监控线程创建时的内存消耗,避免 OOM。
- 线程活动:查看活跃线程数量,是否线程数接近 maximumPoolSize。
2. 在 “线程” (Threads) 选项卡
- 查找线程池的工作线程 
  - 在 Threads选项卡,可以看到所有线程的状态,如RUNNABLE、WAITING、BLOCKED。
- 线程池的线程通常会以 pool-x-thread-y形式命名,可以找到它们的运行状态。
 
- 在 
- 检查线程状态 
  - RUNNABLE:线程正在执行任务,表明线程池有足够的任务。
- WAITING / TIMED_WAITING:线程空闲,可能 corePoolSize设置过高或任务不足。
- BLOCKED:可能多个线程争用资源,如数据库连接、锁竞争。
 
- 观察线程栈 
  - 点击某个线程,可以查看其调用栈,分析是否有任务执行时间过长或死锁。
 
3. 使用 “Sampler” 进行分析
- 在 Sampler选项卡:- 选择 CPU 采样(CPU Sample):查看线程池中的线程 CPU 消耗情况,判断是否 CPU 过载。
- 选择 内存采样(Memory Sample):查看线程占用的对象,避免泄漏。
 
4. 使用 MBeans 监控线程池参数
JVisualVM 支持 JMX(Java Management Extensions),可以通过 MBeans 选项卡直接监控 ThreadPoolExecutor 的相关属性:
- 打开 MBeans 选项卡
- 找到 java.util.concurrent.ThreadPoolExecutor相关的 MBean
- 关注以下属性: 
  - PoolSize:当前线程池中线程数
- ActiveCount:正在执行任务的线程数
- CompletedTaskCount:已完成的任务数
- TaskCount:总任务数
- QueueSize:任务队列大小
- RejectedExecutionCount:被拒绝的任务数(如果有)
 
三、开启 JMX 远程监控(可选)
如果你的应用部署在服务器上,可以开启 JMX 远程监控,让 JVisualVM 连接远程 JVM:
步骤 1:远程服务器上启用 JMX 远程监控
在 远程服务器 启动 Java 应用时,添加 JVM 选项:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
解释:
- -Dcom.sun.management.jmxremote:启用 JMX 远程管理。
- -Dcom.sun.management.jmxremote.port=9010:指定 JMX 监听端口(可以修改)。
- -Dcom.sun.management.jmxremote.ssl=false:禁用 SSL(默认启用,这里为了方便关闭)。
- -Dcom.sun.management.jmxremote.authenticate=false:禁用 JMX 认证(默认启用,生产环境建议开启)。
⚠️ 生产环境建议开启认证和 SSL,防止未经授权访问
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=true
步骤 2:开放防火墙端口(如果需要)
如果服务器启用了 防火墙,需要开放 JMX 端口(例如 9010):
sudo firewall-cmd --zone=public --add-port=9010/tcp --permanent
sudo firewall-cmd --reload
或使用 iptables:
iptables -A INPUT -p tcp --dport 9010 -j ACCEPT
service iptables save
步骤 3:本地使用 JVisualVM 连接远程 JVM
-  启动 JVisualVM jvisualvm
-  添加远程主机 - 在 “应用”(Applications) 面板中,右键 “远程”(Remote) → “添加远程主机”(Add Remote Host)。
- 输入 远程服务器 IP,点击 确定。
 
-  添加 JMX 连接 - 在 远程主机 下,右键 “添加 JMX 连接”(Add JMX Connection)。
- 输入:远程服务器IP:9010
- 取消 “Use SSL”(如果之前未启用 SSL)。
- 点击 确定。
 
-  开始监控 - 连接成功后,可以看到远程 JVM 进程,点击进程即可查看: 
    - 线程(Threads):查看线程池中的线程状态
- CPU、内存使用情况
- 堆转储、垃圾回收
- MBeans(可监控 ThreadPoolExecutor关键参数)
 
 
- 连接成功后,可以看到远程 JVM 进程,点击进程即可查看: 
    
可选:使用 SSH 端口转发(避免开放 JMX 端口)
如果不想直接暴露 JMX 端口,可以使用 SSH 端口转发:
ssh -L 9010:localhost:9010 user@远程服务器IP
然后在 JVisualVM 里连接:
localhost:9010
这样,JMX 连接是通过 SSH 隧道 进行加密的,更加安全。
总结
✅ JVisualVM 远程监控步骤:
- 远程服务器启动时开启 JMX 远程管理(添加 JVM 选项)。
- 确保防火墙开放 JMX 端口(或使用 SSH 端口转发)。
- 本地使用 JVisualVM 连接远程主机并添加 JMX 连接,即可实时监控。
🔹 JVisualVM 比 JConsole 更强大,可以提供更多 JVM 运行时指标、内存分析和垃圾回收日志,适用于更深入的性能优化分析!🚀
四、结合 Prometheus + Grafana 监控
如果需要长期监控线程池状态,可以结合 Micrometer + Prometheus + Grafana:
- 使用 ThreadPoolExecutor的getPoolSize()、getActiveCount()、getQueue().size()进行指标采集。
- 通过 Prometheus 拉取数据,并在 Grafana 中可视化线程池的状态。
总结
JVisualVM 可以实时监控 Java 线程池状态,关键步骤:
- 在 “线程” 选项卡查看活跃线程状态
- 在 “监视” 选项卡监控 CPU 和内存
- 使用 “Sampler” 分析 CPU 和内存消耗
- 在 “MBeans” 选项卡监控线程池关键参数
- 远程应用可使用 JMX 远程监控
- 长期监控可结合 Prometheus + Grafana
这样,你就可以精准分析 Java 线程池的运行情况,找到最优参数调优方向!🚀
