最近做个项目,就是要取得cpu占有率等等的系统信息,一开始以为要用动态链接库了,但后来
发现可以像下面这样做,不去调用jni,这样省去了很多看
新技术的时间o(∩_∩)o...
在Java中,可以获得总的物理
内存、剩余的物理内存、已使用的物理内存等信息,下面
例子可以取得这些信息,并且获得在Windows下的内存使用率。
首先编写一个MonitorInfoBean类,用来装载监控的一些信息,包括物理内存、剩余的物理内存、已使用的物理内存、内存使用率等字段,该类的代码如下:
class="java" name="code">
1. package com.amgkaka.performance;
2.
3. /** *//**
4. * 监视信息的JavaBean类.
5. * @author amg
6. * @version 1.0
7. * Creation date: 2008-4-25 - 上午10:37:00
8. */
9. public class MonitorInfoBean {
10. /** *//** 可使用内存. */
11. private long totalMemory;
12.
13. /** *//** 剩余内存. */
14. private long freeMemory;
15.
16. /** *//** 最大可使用内存. */
17. private long maxMemory;
18.
19. /** *//** 操作系统. */
20. private String osName;
21.
22. /** *//** 总的物理内存. */
23. private long totalMemorySize;
24.
25. /** *//** 剩余的物理内存. */
26. private long freePhysicalMemorySize;
27.
28. /** *//** 已使用的物理内存. */
29. private long usedMemory;
30.
31. /** *//** 线程总数. */
32. private int totalThread;
33.
34. /** *//** cpu使用率. */
35. private double cpuRatio;
36.
37. public long getFreeMemory() {
38. return freeMemory;
39. }
40.
41. public void setFreeMemory(long freeMemory) {
42. this.freeMemory = freeMemory;
43. }
44.
45. public long getFreePhysicalMemorySize() {
46. return freePhysicalMemorySize;
47. }
48.
49. public void setFreePhysicalMemorySize(long freePhysicalMemorySize) {
50. this.freePhysicalMemorySize = freePhysicalMemorySize;
51. }
52.
53. public long getMaxMemory() {
54. return maxMemory;
55. }
56.
57. public void setMaxMemory(long maxMemory) {
58. this.maxMemory = maxMemory;
59. }
60.
61. public String getOsName() {
62. return osName;
63. }
64.
65. public void setOsName(String osName) {
66. this.osName = osName;
67. }
68.
69. public long getTotalMemory() {
70. return totalMemory;
71. }
72.
73. public void setTotalMemory(long totalMemory) {
74. this.totalMemory = totalMemory;
75. }
76.
77. public long getTotalMemorySize() {
78. return totalMemorySize;
79. }
80.
81. public void setTotalMemorySize(long totalMemorySize) {
82. this.totalMemorySize = totalMemorySize;
83. }
84.
85. public int getTotalThread() {
86. return totalThread;
87. }
88.
89. public void setTotalThread(int totalThread) {
90. this.totalThread = totalThread;
91. }
92.
93. public long getUsedMemory() {
94. return usedMemory;
95. }
96.
97. public void setUsedMemory(long usedMemory) {
98. this.usedMemory = usedMemory;
99. }
100.
101. public double getCpuRatio() {
102. return cpuRatio;
103. }
104.
105. public void setCpuRatio(double cpuRatio) {
106. this.cpuRatio = cpuRatio;
107. }
108. }
接着编写一个获得当前的监控信息的
接口,该类的代码如下所示:
1. package com.amgkaka.performance;
2.
3. /** *//**
4. * 获取系统信息的业务逻辑类接口.
5. * @author amg * @version 1.0
6. * Creation date: 2008-3-11 - 上午10:06:06
7. */
8. public interface IMonitorService {
9. /** *//**
10. * 获得当前的监控对象.
11. * @return 返回构造好的监控对象
12. * @throws Exception
13. * @author amgkaka
14. * Creation date: 2008-4-25 - 上午10:45:08
15. */
16. public MonitorInfoBean getMonitorInfoBean() throws Exception;
17.
18. }
该类的实现类MonitorServiceImpl如下所示:
Java代码
1. package com.amgkaka.performance;
2.
3. import java.io.InputStreamReader;
4. import java.io.LineNumberReader;
5.
6. import sun.management.ManagementFactory;
7.
8. import com.sun.management.OperatingSystemMXBean;
9.
10. /** *//**
11. * 获取系统信息的业务逻辑实现类.
12. * @author amg * @version 1.0 Creation date: 2008-3-11 - 上午10:06:06
13. */
14. public class MonitorServiceImpl implements IMonitorService {
15. //可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了
16. private static final int CPUTIME = 5000;
17.
18. private static final int PERCENT = 100;
19.
20. private static final int FAULTLENGTH = 10;
21.
22. /** *//**
23. * 获得当前的监控对象.
24. * @return 返回构造好的监控对象
25. * @throws Exception
26. * @author amg * Creation date: 2008-4-25 - 上午10:45:08
27. */
28. public MonitorInfoBean getMonitorInfoBean() throws Exception {
29. int kb = 1024;
30.
31. // 可使用内存
32. long totalMemory = Runtime.getRuntime().totalMemory() / kb;
33. // 剩余内存
34. long freeMemory = Runtime.getRuntime().freeMemory() / kb;
35. // 最大可使用内存
36. long maxMemory = Runtime.getRuntime().maxMemory() / kb;
37.
38. OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory
39. .getOperatingSystemMXBean();
40.
41. // 操作系统
42. String osName = System.getProperty("os.name");
43. // 总的物理内存
44. long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb;
45. // 剩余的物理内存
46. long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb;
47. // 已使用的物理内存
48. long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb
49. .getFreePhysicalMemorySize())
50. / kb;
51.
52. // 获得线程总数
53. ThreadGroup parentThread;
54. for (parentThread = Thread.currentThread().getThreadGroup(); parentThread
55. .getParent() != null; parentThread = parentThread.getParent())
56. ;
57. int totalThread = parentThread.activeCount();
58.
59. double cpuRatio = 0;
60. if (osName.toLowerCase().startsWith("windows")) {
61. cpuRatio = this.getCpuRatioForWindows();
62. }
63.
64. // 构造返回对象
65. MonitorInfoBean infoBean = new MonitorInfoBean();
66. infoBean.setFreeMemory(freeMemory);
67. infoBean.setFreePhysicalMemorySize(freePhysicalMemorySize);
68. infoBean.setMaxMemory(maxMemory);
69. infoBean.setOsName(osName);
70. infoBean.setTotalMemory(totalMemory);
71. infoBean.setTotalMemorySize(totalMemorySize);
72. infoBean.setTotalThread(totalThread);
73. infoBean.setUsedMemory(usedMemory);
74. infoBean.setCpuRatio(cpuRatio);
75. return infoBean;
76. }
77.
78. /** *//**
79. * 获得CPU使用率.
80. * @return 返回cpu使用率
81. * @author amg * Creation date: 2008-4-25 - 下午06:05:11
82. */
83. private double getCpuRatioForWindows() {
84. try {
85. String procCmd = System.getenv("windir")
86. + "\\system32\\wbem\\wmic.exe process get Caption,CommandLine,"
87. + "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount";
88. // 取进程信息
89. long[] c0 = readCpu(Runtime.getRuntime().exec(procCmd));
90. Thread.sleep(CPUTIME);
91. long[] c1 = readCpu(Runtime.getRuntime().exec(procCmd));
92. if (c0 != null && c1 != null) {
93. long idletime = c1[0] - c0[0];
94. long busytime = c1[1] - c0[1];
95. return Double.valueOf(
96. PERCENT * (busytime) / (busytime + idletime))
97. .doubleValue();
98. } else {
99. return 0.0;
100. }
101. } catch (Exception ex) {
102. ex.printStackTrace();
103. return 0.0;
104. }
105. }
106.
107. /** *//**
108. * 读取CPU信息.
109. * @param proc
110. * @return
111. * @author amg * Creation date: 2008-4-25 - 下午06:10:14
112. */
113. private long[] readCpu(final Process proc) {
114. long[] retn = new long[2];
115. try {
116. proc.getOutputStream().close();
117. InputStreamReader ir = new InputStreamReader(proc.getInputStream());
118. LineNumberReader input = new LineNumberReader(ir);
119. String line = input.readLine();
120. if (line == null || line.length() < FAULTLENGTH) {
121. return null;
122. }
123. int capidx = line.indexOf("Caption");
124. int cmdidx = line.indexOf("CommandLine");
125. int rocidx = line.indexOf("ReadOperationCount");
126. int umtidx = line.indexOf("UserModeTime");
127. int kmtidx = line.indexOf("KernelModeTime");
128. int wocidx = line.indexOf("WriteOperationCount");
129. long idletime = 0;
130. long kneltime = 0;
131. long usertime = 0;
132. while ((line = input.readLine()) != null) {
133. if (line.length() < wocidx) {
134. continue;
135. }
136. // 字段出现顺序:Caption,CommandLine,KernelModeTime,ReadOperationCount,
137. // ThreadCount,UserModeTime,WriteOperation
138. String caption = Bytes.substring(line, capidx, cmdidx - 1)
139. .trim();
140. String cmd = Bytes.substring(line, cmdidx, kmtidx - 1).trim();
141. if (cmd.indexOf("wmic.exe") >= 0) {
142. continue;
143. }
144. // log.info("line="+line);
145. if (caption.equals("System Idle Process")
146. || caption.equals("System")) {
147. idletime += Long.valueOf(
148. Bytes.substring(line, kmtidx, rocidx - 1).trim())
149. .longValue();
150. idletime += Long.valueOf(
151. Bytes.substring(line, umtidx, wocidx - 1).trim())
152. .longValue();
153. continue;
154. }
155.
156. kneltime += Long.valueOf(
157. Bytes.substring(line, kmtidx, rocidx - 1).trim())
158. .longValue();
159. usertime += Long.valueOf(
160. Bytes.substring(line, umtidx, wocidx - 1).trim())
161. .longValue();
162. }
163. retn[0] = idletime;
164. retn[1] = kneltime + usertime;
165. return retn;
166. } catch (Exception ex) {
167. ex.printStackTrace();
168. } finally {
169. try {
170. proc.getInputStream().close();
171. } catch (Exception e) {
172. e.printStackTrace();
173. }
174. }
175. return null;
176. }
177.
178. /** *//**
179. * 测试方法.
180. * @param args
181. * @throws Exception
182. * @author amg * Creation date: 2008-4-30 - 下午04:47:29
183. */
184. public static void main(String[] args) throws Exception {
185. IMonitorService service = new MonitorServiceImpl();
186. MonitorInfoBean monitorInfo = service.getMonitorInfoBean();
187. System.out.println("cpu占有率=" + monitorInfo.getCpuRatio());
188.
189. System.out.println("可使用内存=" + monitorInfo.getTotalMemory());
190. System.out.println("剩余内存=" + monitorInfo.getFreeMemory());
191. System.out.println("最大可使用内存=" + monitorInfo.getMaxMemory());
192.
193. System.out.println("操作系统=" + monitorInfo.getOsName());
194. System.out.println("总的物理内存=" + monitorInfo.getTotalMemorySize() + "kb");
195. System.out.println("剩余的物理内存=" + monitorInfo.getFreeMemory() + "kb");
196. System.out.println("已使用的物理内存=" + monitorInfo.getUsedMemory() + "kb");
197. System.out.println("线程总数=" + monitorInfo.getTotalThread() + "kb");
198. }
}
该实现类中需要用到一个自己编写byte的工具类,该类的代码如下所示:
1. package com.amgkaka.performance;
2.
3. /** *//**
4. * byte操作类.
5. * @author amg * @version 1.0
6. * Creation date: 2008-4-30 - 下午04:57:23
7. */
8. public class Bytes {
9. /** *//**
10. * 由于String.subString对汉字处理存在问题(把一个汉字视为一个字节),因此在
11. * 包含汉字的字符串时存在隐患,现调整如下:
12. * @param src 要截取的字符串
13. * @param start_idx 开始坐标(包括该坐标)
14. * @param end_idx 截止坐标(包括该坐标)
15. * @return
16. */
17. public static String substring(String src, int start_idx, int end_idx){
18. byte[] b = src.getBytes();
19. String tgt = "";
20. for(int i=start_idx; i<=end_idx; i++){
21. tgt +=(char)b[i];
22. }
23. return tgt;
24. }
}
运行下MonitorBeanImpl类,读者将会看到当前的内存、cpu利用率等信息。