JConsole是JDK自带的一款监控程序,其基于JMX协议与JVM进程连接。JConsole带有图形界面,通过该工具我们可以很方便的查看JVM进程中的堆内存情况、GC情况、线程情况等。实际上JDK还自带了很多命令行工具也能实现JConsole的功能,但使用命令行来分析远不如JConsole中的图表直接,一般在开发和测试环境建议都开启JMX的远程连接,这样可以很方便的分析程序的各项运行时指标。
对于本地开发机上的进程JConsole可以直接连接,但如果JVM进程位于服务器上,我们需要暴露JMX协议端口才能连接,这需要在启动Java程序时添加以下JVM参数。
-Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.rmi.port=1099 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
参数中指定了JMX的主机名(具体使用时填写连接时对应主机IP)、端口,以及不开启密码认证、不开启SSL的配置(生产环境可以考虑开启)。JConsole中的远程进程可以通过指定这些参数进行连接。
这里额外要注意的是如果使用k8s容器环境,这里我们就无法填写hostname
主机名了,因为k8s调度下的容器IP不是固定的。此时的最佳解决方案是这样的:我们主机名还是写127.0.0.1
,同时使用kubectl命令,将容器内端口映射到本地,来实现JMX的远程连接。映射命令例子如下。
.\kubectl.exe --kubeconfig ./config port-forward -n dev order-687998bc67-srmjr --address 0.0.0.0 1099:1099
概览面板我们可以看到总堆内存使用情况、线程数、总的类装载量、CPU占用率。
内存面板我们可以分区查看内存各个分代的使用情况。我们可以根据这个面板调整分代内存的初始值,实现最佳的堆内存分配。
线程面板我们可以查看当前虚拟机中的线程信息,以及当前线程的虚拟机栈跟踪信息,我们可以基于这些信息判断连接池状态,以及定位解决死锁问题等。
类面板我们可以看到JVM装载的类信息。
VM概要中我们可以看到当前JVM进程的各种统计指标,以及启动参数等。
MBeans面板用于对Java程序暴露的所有JMXBean进行查看和修改,这部分具体可以参考JMX相关章节。