java 如何获得一个进程的内存使用情况,cpu运行的时间

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 如何获得一个进程的内存使用情况,cpu运行的时间相关的知识,希望对你有一定的参考价值。

首先有个基本问题需要了解一下:
这里所说java里获得一个进程的内存使用情况和cpu运行时间,是指在java内部获取一个纯外部进程的内存与cpu时间呢,还是指在java内部,由java启动的进程的内存与cpu时间。

如果是第一种情况,那你还需要在java内部再起一个进程,通过执行操作系统的shell命令来查看那个进程的运行状态。比如那个外部进程的ID为3119,则执行cat /proc/3119/status | grep VmRSS就可以过滤出该进程的物理内存占用量。

如果是第二种情况,(假定你问的就是这种情况)。
先说内存占用量:一般说来,你可以使用这两种方式获取内存使用情况
方式一:
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage(); //椎内存使用情况
long totalMemorySize = memoryUsage.getInit(); //初始的总内存
long maxMemorySize = memoryUsage.getMax(); //最大可用内存
long usedMemorySize = memoryUsage.getUsed(); //已使用的内存

方式二:
Runtime rt = Runtime.getRuntime();
long totalMemorySize = rt.totalMemory(); //初始的总内存
long maxMemorySiz = t.maxMemory(); //最大可用内存
long freeMemorySize = rt.freeMemory(); //当前可用内存

需要说明的是,这种方式获取的是整个jvm的内存使用情况,并不是某一个进程的内存使用情况,事实上,在java内部,可以使用Rumtime.getRuntime().exec($SHELL)来开启一个外部进程(这里$SHELL代表一个可操作系统的shell命令)。而运行Java程序整个jvm,对于操作系统而言,也仅仅只是一个进程。也就是说,一个jvm就是一个进程,你通过java程序开启的进程都是外部进程,java内部目前还提供了一个destroy方法来销毁该进程,对于该进程的其它信息,都无法直接获取,这些信息的获取,显然需要本地化(Local)的实现。既然标准jdk库没有,就不可能再通过平台无关的代码来实现了。典型的做法就是使用前面第一种情况的方式,再启一个进程,执行shell命令来获取。

不过对于cpu使用时间,采用标准java代码倒是可以拿到。由于java的语法很啰嗦,举一个较完全的例子需要太多的代码,我这里就只写最关键的代码:
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
① long currentCpuTime = threadMXBean.getCurrentThreadCpuTime(); //当前线程的cpu使用时间
long someThreadId = 709817L; //假定有某个线程的ID是709817
② long someThreadCpuTime = threadMXBean.getThreadCpuTime(someThreadId); //获取ID为someThreadId即709817的线程的cpu时间

基于上面的核心api,你可以把由java启动的外部进程放到一个单独的线程中执行,再用代码②的方式来获取该进程的cpu使用时间,也可以将外部进程放入到当前线程中执行,用① 的方式来获得进程的cpu使用时间。
参考技术A C#都可以,JAVA为什么不行?难道就因为操作系统是微软的?没道理的 参考技术B 好像java无法直接获取进程
所以不能查看进程的那些信息

关于在zabbix监测脚本中使用ps命令监控进程CPU使用率和内存使用率,获得数据为0的情况描述

前提:想自己编写zabbix监测脚本,然后通过配置模板的方式,实现对资源(cpu和内存)使用率高的进程进行监控。

过程描述:
zabbix版本为2.21,被监控主机操作系统为CentOS 6.4。
脚本中主要命令如下:
percent=0;

#通过脚本输入参数
process=$1;

#通过ps aux参数,获取CPU%和MEM%值,使用awk将第四行的MEM%值筛选出来
percent=ps aux | grep $process | grep -v grep | head -1 | awk ‘{print $4}‘;

echo $percent

问题描述:
发现在cli中运行上述脚本命令可以获取到进程资源使用率对应的数值。
但是脚本中包含相同命令条件下,执行脚本,却经常获得的数值为0.0,而仅仅只更改了脚本输入的$1,也就是输入进程名,脚本执行后,获得的数值往往不为0.0,而为正常数据。

影响:
由于在zabbix的web页面中,配置了关于该项数据的dataview,直接导致了dataview的数据展示不准确。

解决方法(待验证):
1.使用内置的zabbix变量proc.cpu.util[<name>,<user>,<type>,<cmdline>,<mode>,<zone>] 和proc.mem.util[<name>,<user>,<type>,<cmdline>,<mode>,<zone>]。

2.修改脚本中的命令,改用如下方法:
首先获取进程名对应的pid,再结合top运行如下命令:
top -b -n 1 -p $pid 2>&1 | awk -v pid=$pid ‘{if ($1 == pid)print $9}‘

3.修改脚本中的命令,改用如下方法:
首先获取进程名对应的pid,再从/proc/$pid/目录下读取相关数据,进行计算获得。

后记:没有对以上三种解决方法进行验证,但是个人觉得还是使用zabbix内置变量配置模板为比较好的解决办法,毕竟个人能力有限,还是选择相信专业的zabbix吧。

以上是关于java 如何获得一个进程的内存使用情况,cpu运行的时间的主要内容,如果未能解决你的问题,请参考以下文章

获取进程的CPU和内存使用情况的正确性能计数器是什么?

关于在zabbix监测脚本中使用ps命令监控进程CPU使用率和内存使用率,获得数据为0的情况描述

查看本机CPU内存使用率前10的进程

如何使用 WMI 了解进程的 CPU 和内存使用情况?

使用 PerformanceCounter 跟踪每个进程的内存和 CPU 使用情况?

java如何获取系统内存、cpu等信息。