import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.management.ManagementFactory;
import org.apache.log4j.Logger;
import com.sun.management.OperatingSystemMXBean;
public class MonitorUtil {
private static final Logger logger = Logger.getLogger(MonitorUtil.class);
//可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了
private static final int CPUTIME = 5000;
private static final int PERCENT = 100;
private static final int FAULTLENGTH = 10;
/** *//**
* 获得当前的监控对象.
*/
public static String getMonitorInfoBean() throws Exception {
int kb = 1024;
// 可使用内存
long totalMemory = Runtime.getRuntime().totalMemory() / kb;
// 剩余内存
long freeMemory = Runtime.getRuntime().freeMemory() / kb;
// 最大可使用内存
long maxMemory = Runtime.getRuntime().maxMemory() / kb;
OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
// 操作系统
String osName = System.getProperty("os.name");
// 总的物理内存
long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;
// 剩余的物理内存
long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;
// 已使用的物理内存
long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb
.getFreePhysicalMemorySize())
/ kb;
// 获得线程总数
ThreadGroup parentThread;
for (parentThread = Thread.currentThread().getThreadGroup(); parentThread
.getParent() != null; parentThread = parentThread.getParent())
;
int totalThread = parentThread.activeCount();
double cpuRatio = 0;
if (osName.toLowerCase().startsWith("windows")) {
cpuRatio = getCpuRatioForWindows();
}
StringBuffer sb = new StringBuffer();
double total = (Runtime.getRuntime().totalMemory()) / (1024.0 * 1024);
double max = (Runtime.getRuntime().maxMemory()) / (1024.0 * 1024);
double free = (Runtime.getRuntime().freeMemory()) / (1024.0 * 1024);
logger.info("Java 虚拟机试图使用的最大内存量(当前JVM的最大可用内存) maxMemory(): " + max + "MB<br/>");
logger.info("Java 虚拟机中的内存总量(当前JVM占用的内存总数) totalMemory(): " + total + "MB<br/>");
logger.info("Java 虚拟机中的空闲内存量(当前JVM空闲内存) freeMemory(): " + free + "MB<br/>");
logger.info("因为JVM只有在需要内存时才占用物理内存使用,所以freeMemory()的值一般情况下都很小,<br/>" +
"而JVM实际可用内存并不等于freeMemory(),而应该等于 maxMemory() - totalMemory() + freeMemory()。<br/>");
logger.info("JVM实际可用内存: " + (max - total + free) + "MB<br/>");
logger.info("cpu占有率=" + cpuRatio+"/n");
logger.info("可使用内存=" + totalMemory+"/n");
logger.info("剩余内存=" + freeMemory+"/n");
logger.info("最大可使用内存=" + maxMemory+"/n");
logger.info("操作系统=" + osName+"/n");
logger.info("总的物理内存=" + totalMemorySize + "kb/n");
logger.info("剩余的物理内存=" + freeMemory + "kb/n");
logger.info("已使用的物理内存=" + usedMemory + "kb/n");
logger.info("线程总数=" + totalThread+ "/n");
return sb.toString();
}
/** *//**
* 获得CPU使用率.
*/
private static double getCpuRatioForWindows() {
try {
String procCmd = System.getenv("windir")
+ "\\system32\\wbem\\wmic.exe process get Caption,CommandLine,"
+ "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount";
// 取进程信息
long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));
Thread.sleep(CPUTIME);
long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));
if (c0 != null && c1 != null) {
long idletime = c1[0] - c0[0];
long busytime = c1[1] - c0[1];
return Double.valueOf(
PERCENT * (busytime) / (busytime + idletime))
.doubleValue();
} else {
return 0.0;
}
} catch (Exception ex) {
ex.printStackTrace();
return 0.0;
}
}
/** *//**
* 读取CPU信息.
*/
private static long[] readCpu(final Process proc) {
long[] retn = new long[2];
try {
proc.getOutputStream().close();
InputStreamReader ir = new InputStreamReader(proc.getInputStream());
LineNumberReader input = new LineNumberReader(ir);
String line = input.readLine();
if (line == null || line.length() < FAULTLENGTH) {
return null;
}
int capidx = line.indexOf("Caption");
int cmdidx = line.indexOf("CommandLine");
int rocidx = line.indexOf("ReadOperationCount");
int umtidx = line.indexOf("UserModeTime");
int kmtidx = line.indexOf("KernelModeTime");
int wocidx = line.indexOf("WriteOperationCount");
long idletime = 0;
long kneltime = 0;
long usertime = 0;
while ((line = input.readLine()) != null) {
if (line.length() < wocidx) {
continue;
}
// 字段出现顺序:Caption,CommandLine,KernelModeTime,ReadOperationCount,
// ThreadCount,UserModeTime,WriteOperation
String caption = substring(line, capidx, cmdidx - 1)
.trim();
String cmd = substring(line, cmdidx, kmtidx - 1).trim();
if (cmd.indexOf("wmic.exe") >= 0) {
continue;
}
// log.info("line="+line);
if (caption.equals("System Idle Process")
|| caption.equals("System")) {
idletime += Long.valueOf(
substring(line, kmtidx, rocidx - 1).trim())
.longValue();
idletime += Long.valueOf(
substring(line, umtidx, wocidx - 1).trim())
.longValue();
continue;
}
kneltime += Long.valueOf(
substring(line, kmtidx, rocidx - 1).trim())
.longValue();
usertime += Long.valueOf(
substring(line, umtidx, wocidx - 1).trim())
.longValue();
}
retn[0] = idletime;
retn[1] = kneltime + usertime;
return retn;
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
proc.getInputStream().close();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/** *//**
* 由于String.subString对汉字处理存在问题:
* @param src 要截取的字符串
* @param start_idx 开始坐标(包括该坐标)
* @param end_idx 截止坐标(包括该坐标)
* @return
*/
public static String substring(String src, int start_idx, int end_idx){
byte[] b = src.getBytes();
String tgt = "";
for(int i=start_idx; i<=end_idx; i++){
tgt +=(char)b[i];
}
return tgt;
}
}