最近项目需要对Java进程,堆栈信息,内存,cpu等资源的消耗进行监控,借鉴了git已有的轮子JPOM java项目管理系统和在线demo网站及对其源码的分析,提炼出了以下几种监控方式。
1.引言
有两种途径可以监控Java进程及对应JVM信息:
一.使用JDK自带rt.jar中 java.lang.management包下的类来管理。java.lang.management包提供了全面的监控和管理工具,包括JVM的监管API、监管API日志、jconsole和其他监控工具、Java管理扩展平台(JMX)等等。
类名 | 描述 |
---|---|
ClassLoadingMXBean | 用于 Java 虚拟机的类加载系统的管理接口。 |
CompilationMXBean | 用于 Java 虚拟机的编译系统的管理接口。 |
GarbageCollectorMXBean | 用于 Java 虚拟机的垃圾回收的管理接口。 |
MemoryManagerMXBean | 内存管理器的管理接口。 |
MemoryMXBean | Java 虚拟机的内存系统的管理接口。 |
MemoryPoolMXBean | 内存池的管理接口。 |
OperatingSystemMXBean | 用于操作系统的管理接口,Java 虚拟机在此操作系统上运行。 |
RuntimeMXBean | Java 虚拟机的运行时系统的管理接口。 |
ThreadMXBean | Java 虚拟机线程系统的管理接口。 |
二 . 使用系统和JVM提供的命令来获取。
如导出堆栈信息: jmap -heap 2576 > JVMHeap.log
进程线程信息:jstack 2576 >> JVMjstack.log
内存使用情况:
window: tasklist /V /FI "pid eq 5027"
linux : top -b -n 1 -p 5027
2. 程序启停, 为进程自定义项目名称
Linux: 启动命令
String command = String.format("nohup java %s %s -Dapplication=%s -Dbasedir=%s %s %s >> %s 2>&1 &",
projectInfoModel.getJvm(),
ProjectInfoModel.getClassPathLib(projectInfoModel),
projectInfoModel.getId(),
projectInfoModel.getAbsoluteLib(),
projectInfoModel.getMainClass(),
projectInfoModel.getArgs(),
projectInfoModel.getAbsoluteLog());
Linux停止
kill %s
Window启动
String command = String.format("javaw %s %s -Dapplication=%s -Dbasedir=%s %s %s >> %s &",
jvm, classPath, tag,
projectInfoModel.getAbsoluteLib(), mainClass, args, projectInfoModel.getAbsoluteLog());
Window停止
taskkill /F /PID %s
tips: -D
在虚拟机的系统属性中设置属性名/值对,运行在此虚拟机之上的应用程序可用System.getProperty(“propertyName”)得到value的值。如果value中有空格,则需要用双引号将该值括起来,如-Dname=”space string”。该参数通常用于设置系统级全局变量值,如配置文件路径,应为该属性在程序中任何地方都可访问。
启动命令中添加 -Dapplication=%s 参数来将Project Name加入进程的JVM信息中,后续访问可根据Project Name确定唯一的进程Pid。
Properties properties = virtualMachine.getAgentProperties();
String args = properties.getProperty("sun.jvm.args", "");
if (StrUtil.containsIgnoreCase(args, appTag)) {
return virtualMachine;
}
args = properties.getProperty("sun.java.command", "");
if (StrUtil.containsIgnoreCase(args, appTag)) {
return virtualMachine;
}
3. 操作系统判断
使用System.getProperties() 来获取操作系统配置参数: 如System.getProperty("os.name")获取当前操作系统。
Key | Description of Associated Value | 中文描述 |
---|---|---|
java.version | Java Runtime Environment version | Java 运行时环境版本 |
java.vendor | Java Runtime Environment vendor | Java 运行时环境供应商 |
java.vendor.url | Java vendor URL | Java 供应商的 URL |
java.home | Java installation directory | Java 安装目录 |
java.vm.specification.version | Java Virtual Machine specification version | Java 虚拟机规范版本 |
java.vm.specification.vendor | Java Virtual Machine specification vendor | Java 虚拟机规范供应商 |
java.vm.specification.name | Java Virtual Machine specification name | Java 虚拟机规范名称 |
java.vm.version | Java Virtual Machine implementation version | Java 虚拟机实现版本 |
java.vm.vendor | Java Virtual Machine implementation vendor | Java 虚拟机实现供应商 |
java.vm.name | Java Virtual Machine implementation name | Java 虚拟机实现名称 |
java.specification.version | Java Runtime Environment specification version | Java 运行时环境规范版本 |
java.specification.vendor | Java Runtime Environment specification vendor | Java 运行时环境规范供应商 |
java.specification.name | Java Runtime Environment specification name | Java 运行时环境规范名称 |
java.class.version | Java class format version number | Java 类格式版本号 |
java.class.path | Java class path | Java 类路径 |
java.library.path | List of paths to search when loading libraries | 加载库时搜索的路径列表 |
java.io.tmpdir | Default temp file path | 默认的临时文件路径 |
java.compiler | Name of JIT compiler to use | 要使用的 JIT 编译器的名称 |
java.ext.dirs | Path of extension directory or directories | 一个或多个扩展目录的路径 |
os.name | Operating system name | 操作系统的名称 |
os.arch | Operating system architecture | 操作系统的架构 |
os.version | Operating system version | 操作系统的版本 |
file.separator | File separator ("/" on UNIX) | 文件分隔符(在 UNIX 系统中是“/”) |
path.separator | Path separator (":" on UNIX) | 路径分隔符(在 UNIX 系统中是“:”) |
line.separator | Line separator ("\n" on UNIX) | 行分隔符(在 UNIX 系统中是“/n”) |
user.name | User's account name | 用户的账户名称 |
user.home | User's home directory | 用户的主目录 |
user.dir | User's current working directory | 用户的当前工作目录 |
或者使用OperatingSystemMXBean系统类来获取
OperatingSystemMXBean op = ManagementFactory.getOperatingSystemMXBean();
System.out.println("Architecture: " + op.getArch());
System.out.println("Processors: " + op.getAvailableProcessors());
System.out.println("System name: " + op.getName());
System.out.println("System version: " + op.getVersion());
System.out.println("Last minute load: " + op.getSystemLoadAverage());