JMX 怎么把 JVM 的指标和自己的组件变成可管理的 MBean?这篇用平台 MBean、自己写的 MBean、通知和一个真实的远程连接逐项验证(JFR 在前一篇,NMT 在后面)。
平台 MBeanServer 的域:[JMImplementation, com.sun.management, java.lang, java.nio, java.util.logging, jdk.management.jfr];MBean 总数 = 27 java.lang 域里的 MBean 类型:[ClassLoading, Compilation, GarbageCollector, Memory, MemoryManager, MemoryPool, OperatingSystem, Runtime, Threading] 读 java.lang:type=Runtime 的 VmName = OpenJDK 64-Bit Server VM,SpecVersion = 21,Uptime >= 0:true Threading 的 ThreadCount = 6,PeakThreadCount = 6;调用操作 findDeadlockedThreads → null GarbageCollector G1 Young Generation:CollectionCount = 0,MemoryPoolNames 个数 = 3 GarbageCollector G1 Old Generation:CollectionCount = 0,MemoryPoolNames 个数 = 3 GarbageCollector G1 Concurrent GC:CollectionCount = 0,MemoryPoolNames 个数 = 1 MBeanInfo(Memory):属性 [ObjectPendingFinalizationCount, HeapMemoryUsage, NonHeapMemoryUsage, Verbose, ObjectName],操作 [gc]
注册 Standard MBean(接口名必须是 类名 + MBean):isRegistered = true MBeanInfo:属性 [MaxSize(读写), Name(只读), Size(只读)],操作 [put, clear] getAttribute(Name) = demo-cache;setAttribute(MaxSize, 2) 之后 MaxSize = 2 invoke put:1,2;Size = 2 第三次 put 抛的是 RuntimeMBeanException,getCause = java.lang.IllegalStateException: cache full setAttribute 一个只读属性 Size → AttributeNotFoundException: Read-only attribute: Size getAttribute 一个不存在的属性 → AttributeNotFoundException: No such attribute: Nope 用同一个 ObjectName 再注册一次 → InstanceAlreadyExistsException 注册一个不符合 MBean 规范的对象 → NotCompliantMBeanException clear() 之后 Size = 0 按模式查询 demo:* → [demo:type=Cache,name=main]
两次 setAttribute 之后收到的通知:
MaxSize: 100 → 10 (seq 1,listener 线程 = main)
MaxSize: 10 → 20 (seq 2,listener 线程 = main)
通知是在调用 setAttribute 的线程里同步发出的吗:true
unregisterMBean 之后 isRegistered = false连接成功,用时 105 ms;远程 MBean 数 = 28,远程 JVM 的 pid 属性 Name = 65302@bogon 远程调用自定义 MBean:Count = 0;invoke incr → 1,2;Count = 2 远程 getAttribute 1000 次:平均 146.69 µs/次(RMI 往返,回环地址)