最近做個項目,就是要取得cpu占有率等等的系統(tǒng)信息,一開始以為要用動態(tài)鏈接庫了,但后來發(fā)現(xiàn)可以像下面這樣做,不去調(diào)用jni,這樣省去了很多看新技術(shù)的時間o(∩_∩)o...
在Java中,可以獲得總的物理內(nèi)存、剩余的物理內(nèi)存、已使用的物理內(nèi)存等信息,下面例子可以取得這些信息,并且獲得在Windows下的內(nèi)存使用率。
首先編寫一個MonitorInfoBean類,用來裝載監(jiān)控的一些信息,包括物理內(nèi)存、剩余的物理內(nèi)存、已使用的物理內(nèi)存、內(nèi)存使用率等字段,該類的代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
package com.amgkaka.performance; /** */ /** * 監(jiān)視信息的JavaBean類. * @author amg * @version 1.0 * Creation date: 2008-4-25 - 上午10:37:00 */ public class MonitorInfoBean { /** */ /** 可使用內(nèi)存. */ private long totalMemory; /** */ /** 剩余內(nèi)存. */ private long freeMemory; /** */ /** 最大可使用內(nèi)存. */ private long maxMemory; /** */ /** 操作系統(tǒng). */ private String osName; /** */ /** 總的物理內(nèi)存. */ private long totalMemorySize; /** */ /** 剩余的物理內(nèi)存. */ private long freePhysicalMemorySize; /** */ /** 已使用的物理內(nèi)存. */ private long usedMemory; /** */ /** 線程總數(shù). */ private int totalThread; /** */ /** cpu使用率. */ private double cpuRatio; public long getFreeMemory() { return freeMemory; } public void setFreeMemory( long freeMemory) { this .freeMemory = freeMemory; } public long getFreePhysicalMemorySize() { return freePhysicalMemorySize; } public void setFreePhysicalMemorySize( long freePhysicalMemorySize) { this .freePhysicalMemorySize = freePhysicalMemorySize; } public long getMaxMemory() { return maxMemory; } public void setMaxMemory( long maxMemory) { this .maxMemory = maxMemory; } public String getOsName() { return osName; } public void setOsName(String osName) { this .osName = osName; } public long getTotalMemory() { return totalMemory; } public void setTotalMemory( long totalMemory) { this .totalMemory = totalMemory; } public long getTotalMemorySize() { return totalMemorySize; } public void setTotalMemorySize( long totalMemorySize) { this .totalMemorySize = totalMemorySize; } public int getTotalThread() { return totalThread; } public void setTotalThread( int totalThread) { this .totalThread = totalThread; } public long getUsedMemory() { return usedMemory; } public void setUsedMemory( long usedMemory) { this .usedMemory = usedMemory; } public double getCpuRatio() { return cpuRatio; } public void setCpuRatio( double cpuRatio) { this .cpuRatio = cpuRatio; } } |
接著編寫一個獲得當(dāng)前的監(jiān)控信息的接口,該類的代碼如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package com.amgkaka.performance; /** */ /** * 獲取系統(tǒng)信息的業(yè)務(wù)邏輯類接口. * @author amg * @version 1.0 * Creation date: 2008-3-11 - 上午10:06:06 */ public interface IMonitorService { /** */ /** * 獲得當(dāng)前的監(jiān)控對象. * @return 返回構(gòu)造好的監(jiān)控對象 * @throws Exception * @author amgkaka * Creation date: 2008-4-25 - 上午10:45:08 */ public MonitorInfoBean getMonitorInfoBean() throws Exception; } |
該類的實現(xiàn)類MonitorServiceImpl如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
package com.amgkaka.performance; import java.io.InputStreamReader; import java.io.LineNumberReader; import sun.management.ManagementFactory; import com.sun.management.OperatingSystemMXBean; /** */ /** * 獲取系統(tǒng)信息的業(yè)務(wù)邏輯實現(xiàn)類. * @author amg * @version 1.0 Creation date: 2008-3-11 - 上午10:06:06 */ public class MonitorServiceImpl implements IMonitorService { //可以設(shè)置長些,防止讀到運行此次系統(tǒng)檢查時的cpu占用率,就不準(zhǔn)了 private static final int CPUTIME = 5000 ; private static final int PERCENT = 100 ; private static final int FAULTLENGTH = 10 ; /** */ /** * 獲得當(dāng)前的監(jiān)控對象. * @return 返回構(gòu)造好的監(jiān)控對象 * @throws Exception * @author amg * Creation date: 2008-4-25 - 上午10:45:08 */ public MonitorInfoBean getMonitorInfoBean() throws Exception { int kb = 1024 ; // 可使用內(nèi)存 long totalMemory = Runtime.getRuntime().totalMemory() / kb; // 剩余內(nèi)存 long freeMemory = Runtime.getRuntime().freeMemory() / kb; // 最大可使用內(nèi)存 long maxMemory = Runtime.getRuntime().maxMemory() / kb; OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory .getOperatingSystemMXBean(); // 操作系統(tǒng) String osName = System.getProperty( "os.name" ); // 總的物理內(nèi)存 long totalMemorySize = osmxb.getTotalPhysicalMemorySize() / kb; // 剩余的物理內(nèi)存 long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / kb; // 已使用的物理內(nèi)存 long usedMemory = (osmxb.getTotalPhysicalMemorySize() - osmxb .getFreePhysicalMemorySize()) / kb; // 獲得線程總數(shù) 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 = this .getCpuRatioForWindows(); } // 構(gòu)造返回對象 MonitorInfoBean infoBean = new MonitorInfoBean(); infoBean.setFreeMemory(freeMemory); infoBean.setFreePhysicalMemorySize(freePhysicalMemorySize); infoBean.setMaxMemory(maxMemory); infoBean.setOsName(osName); infoBean.setTotalMemory(totalMemory); infoBean.setTotalMemorySize(totalMemorySize); infoBean.setTotalThread(totalThread); infoBean.setUsedMemory(usedMemory); infoBean.setCpuRatio(cpuRatio); return infoBean; } /** */ /** * 獲得CPU使用率. * @return 返回cpu使用率 * @author amg * Creation date: 2008-4-25 - 下午06:05:11 */ private double getCpuRatioForWindows() { try { String procCmd = System.getenv( "windir" ) + "\\system32\\wbem\\wmic.exe process get Caption,CommandLine," + "KernelModeTime,ReadOperationCount,ThreadCount,UserModeTime,WriteOperationCount" ; // 取進(jìn)程信息 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信息. * @param proc * @return * @author amg * Creation date: 2008-4-25 - 下午06:10:14 */ private 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 ; } // 字段出現(xiàn)順序:Caption,CommandLine,KernelModeTime,ReadOperationCount, // ThreadCount,UserModeTime,WriteOperation String caption = Bytes.substring(line, capidx, cmdidx - 1 ) .trim(); String cmd = Bytes.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( Bytes.substring(line, kmtidx, rocidx - 1 ).trim()) .longValue(); idletime += Long.valueOf( Bytes.substring(line, umtidx, wocidx - 1 ).trim()) .longValue(); continue ; } kneltime += Long.valueOf( Bytes.substring(line, kmtidx, rocidx - 1 ).trim()) .longValue(); usertime += Long.valueOf( Bytes.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 ; } /** */ /** * 測試方法. * @param args * @throws Exception * @author amg * Creation date: 2008-4-30 - 下午04:47:29 */ public static void main(String[] args) throws Exception { IMonitorService service = new MonitorServiceImpl(); MonitorInfoBean monitorInfo = service.getMonitorInfoBean(); System.out.println( "cpu占有率=" + monitorInfo.getCpuRatio()); System.out.println( "可使用內(nèi)存=" + monitorInfo.getTotalMemory()); System.out.println( "剩余內(nèi)存=" + monitorInfo.getFreeMemory()); System.out.println( "最大可使用內(nèi)存=" + monitorInfo.getMaxMemory()); System.out.println( "操作系統(tǒng)=" + monitorInfo.getOsName()); System.out.println( "總的物理內(nèi)存=" + monitorInfo.getTotalMemorySize() + "kb" ); System.out.println( "剩余的物理內(nèi)存=" + monitorInfo.getFreeMemory() + "kb" ); System.out.println( "已使用的物理內(nèi)存=" + monitorInfo.getUsedMemory() + "kb" ); System.out.println( "線程總數(shù)=" + monitorInfo.getTotalThread() + "kb" ); } } |
該實現(xiàn)類中需要用到一個自己編寫byte的工具類,該類的代碼如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package com.amgkaka.performance; /** */ /** * byte操作類. * @author amg * @version 1.0 * Creation date: 2008-4-30 - 下午04:57:23 */ public class Bytes { /** */ /** * 由于String.subString對漢字處理存在問題(把一個漢字視為一個字節(jié)),因此在 * 包含漢字的字符串時存在隱患,現(xiàn)調(diào)整如下: * @param src 要截取的字符串 * @param start_idx 開始坐標(biāo)(包括該坐標(biāo)) * @param end_idx 截止坐標(biāo)(包括該坐標(biāo)) * @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; } } |
運行下MonitorBeanImpl類,讀者將會看到當(dāng)前的內(nèi)存、cpu利用率等信息。
PS:得到局域網(wǎng)內(nèi)所有主機名的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
import java.net.InetAddress; import java.net.UnknownHostException; public class A { static public void main(String[] args) { try { //通過主機名稱得到IP地址 InetAddress address = InetAddress.getByName( "192.168.9.148" ); System.out.println( "192.168.9.148" + ": " +address.getHostAddress()); // 通過IP得到主機名稱 String ips= "192.168.9." ,ip; InetAddress addip; for ( int i= 148 ;i< 255 ;i++){ ip=ips+i; addip=InetAddress.getByName(ip); System.out.println(ip+ ": " +addip.getHostName()); } } catch (UnknownHostException uhe) { System.err.println( "Unable to find: " + "192.168.9.148" ); } } } |