使用Java代码获取服务器性能信息及局域网内主机名
最近做个项目,就是要取得cpu占有率等等的系统信息,一开始以为要用动态链接库了,但后来发现可以像下面这样做,不去调用jni,这样省去了很多看新技术的时间o(∩_∩)o...
在Java中,可以获得总的物理内存、剩余的物理内存、已使用的物理内存等信息,下面例子可以取得这些信息,并且获得在Windows下的内存使用率。
首先编写一个MonitorInfoBean类,用来装载监控的一些信息,包括物理内存、剩余的物理内存、已使用的物理内存、内存使用率等字段,该类的代码如下:
packagecom.amgkaka.performance; /***//** *监视信息的JavaBean类. *@authoramg *@version1.0 *Creationdate:2008-4-25-上午10:37:00 */ publicclassMonitorInfoBean{ /***//**可使用内存.*/ privatelongtotalMemory; /***//**剩余内存.*/ privatelongfreeMemory; /***//**最大可使用内存.*/ privatelongmaxMemory; /***//**操作系统.*/ privateStringosName; /***//**总的物理内存.*/ privatelongtotalMemorySize; /***//**剩余的物理内存.*/ privatelongfreePhysicalMemorySize; /***//**已使用的物理内存.*/ privatelongusedMemory; /***//**线程总数.*/ privateinttotalThread; /***//**cpu使用率.*/ privatedoublecpuRatio; publiclonggetFreeMemory(){ returnfreeMemory; } publicvoidsetFreeMemory(longfreeMemory){ this.freeMemory=freeMemory; } publiclonggetFreePhysicalMemorySize(){ returnfreePhysicalMemorySize; } publicvoidsetFreePhysicalMemorySize(longfreePhysicalMemorySize){ this.freePhysicalMemorySize=freePhysicalMemorySize; } publiclonggetMaxMemory(){ returnmaxMemory; } publicvoidsetMaxMemory(longmaxMemory){ this.maxMemory=maxMemory; } publicStringgetOsName(){ returnosName; } publicvoidsetOsName(StringosName){ this.osName=osName; } publiclonggetTotalMemory(){ returntotalMemory; } publicvoidsetTotalMemory(longtotalMemory){ this.totalMemory=totalMemory; } publiclonggetTotalMemorySize(){ returntotalMemorySize; } publicvoidsetTotalMemorySize(longtotalMemorySize){ this.totalMemorySize=totalMemorySize; } publicintgetTotalThread(){ returntotalThread; } publicvoidsetTotalThread(inttotalThread){ this.totalThread=totalThread; } publiclonggetUsedMemory(){ returnusedMemory; } publicvoidsetUsedMemory(longusedMemory){ this.usedMemory=usedMemory; } publicdoublegetCpuRatio(){ returncpuRatio; } publicvoidsetCpuRatio(doublecpuRatio){ this.cpuRatio=cpuRatio; } }
接着编写一个获得当前的监控信息的接口,该类的代码如下所示:
packagecom.amgkaka.performance; /***//** *获取系统信息的业务逻辑类接口. *@authoramg*@version1.0 *Creationdate:2008-3-11-上午10:06:06 */ publicinterfaceIMonitorService{ /***//** *获得当前的监控对象. *@return返回构造好的监控对象 *@throwsException *@authoramgkaka *Creationdate:2008-4-25-上午10:45:08 */ publicMonitorInfoBeangetMonitorInfoBean()throwsException; }
该类的实现类MonitorServiceImpl如下所示:
packagecom.amgkaka.performance; importjava.io.InputStreamReader; importjava.io.LineNumberReader; importsun.management.ManagementFactory; importcom.sun.management.OperatingSystemMXBean; /***//** *获取系统信息的业务逻辑实现类. *@authoramg*@version1.0Creationdate:2008-3-11-上午10:06:06 */ publicclassMonitorServiceImplimplementsIMonitorService{ //可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了 privatestaticfinalintCPUTIME=5000; privatestaticfinalintPERCENT=100; privatestaticfinalintFAULTLENGTH=10; /***//** *获得当前的监控对象. *@return返回构造好的监控对象 *@throwsException *@authoramg*Creationdate:2008-4-25-上午10:45:08 */ publicMonitorInfoBeangetMonitorInfoBean()throwsException{ intkb=1024; //可使用内存 longtotalMemory=Runtime.getRuntime().totalMemory()/kb; //剩余内存 longfreeMemory=Runtime.getRuntime().freeMemory()/kb; //最大可使用内存 longmaxMemory=Runtime.getRuntime().maxMemory()/kb; OperatingSystemMXBeanosmxb=(OperatingSystemMXBean)ManagementFactory .getOperatingSystemMXBean(); //操作系统 StringosName=System.getProperty("os.name"); //总的物理内存 longtotalMemorySize=osmxb.getTotalPhysicalMemorySize()/kb; //剩余的物理内存 longfreePhysicalMemorySize=osmxb.getFreePhysicalMemorySize()/kb; //已使用的物理内存 longusedMemory=(osmxb.getTotalPhysicalMemorySize()-osmxb .getFreePhysicalMemorySize()) /kb; //获得线程总数 ThreadGroupparentThread; for(parentThread=Thread.currentThread().getThreadGroup();parentThread .getParent()!=null;parentThread=parentThread.getParent()) ; inttotalThread=parentThread.activeCount(); doublecpuRatio=0; if(osName.toLowerCase().startsWith("windows")){ cpuRatio=this.getCpuRatioForWindows(); } //构造返回对象 MonitorInfoBeaninfoBean=newMonitorInfoBean(); 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); returninfoBean; } /***//** *获得CPU使用率. *@return返回cpu使用率 *@authoramg*Creationdate:2008-4-25-下午06:05:11 */ privatedoublegetCpuRatioForWindows(){ try{ StringprocCmd=System.getenv("windir") +"\\system32\\wbem\\wmic.exeprocessgetCaption,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){ longidletime=c1[0]-c0[0]; longbusytime=c1[1]-c0[1]; returnDouble.valueOf( PERCENT*(busytime)/(busytime+idletime)) .doubleValue(); }else{ return0.0; } }catch(Exceptionex){ ex.printStackTrace(); return0.0; } } /***//** *读取CPU信息. *@paramproc *@return *@authoramg*Creationdate:2008-4-25-下午06:10:14 */ privatelong[]readCpu(finalProcessproc){ long[]retn=newlong[2]; try{ proc.getOutputStream().close(); InputStreamReaderir=newInputStreamReader(proc.getInputStream()); LineNumberReaderinput=newLineNumberReader(ir); Stringline=input.readLine(); if(line==null||line.length()<FAULTLENGTH){ returnnull; } intcapidx=line.indexOf("Caption"); intcmdidx=line.indexOf("CommandLine"); introcidx=line.indexOf("ReadOperationCount"); intumtidx=line.indexOf("UserModeTime"); intkmtidx=line.indexOf("KernelModeTime"); intwocidx=line.indexOf("WriteOperationCount"); longidletime=0; longkneltime=0; longusertime=0; while((line=input.readLine())!=null){ if(line.length()<wocidx){ continue; } //字段出现顺序:Caption,CommandLine,KernelModeTime,ReadOperationCount, //ThreadCount,UserModeTime,WriteOperation Stringcaption=Bytes.substring(line,capidx,cmdidx-1) .trim(); Stringcmd=Bytes.substring(line,cmdidx,kmtidx-1).trim(); if(cmd.indexOf("wmic.exe")>=0){ continue; } //log.info("line="+line); if(caption.equals("SystemIdleProcess") ||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; returnretn; }catch(Exceptionex){ ex.printStackTrace(); }finally{ try{ proc.getInputStream().close(); }catch(Exceptione){ e.printStackTrace(); } } returnnull; } /***//** *测试方法. *@paramargs *@throwsException *@authoramg*Creationdate:2008-4-30-下午04:47:29 */ publicstaticvoidmain(String[]args)throwsException{ IMonitorServiceservice=newMonitorServiceImpl(); MonitorInfoBeanmonitorInfo=service.getMonitorInfoBean(); System.out.println("cpu占有率="+monitorInfo.getCpuRatio()); System.out.println("可使用内存="+monitorInfo.getTotalMemory()); System.out.println("剩余内存="+monitorInfo.getFreeMemory()); System.out.println("最大可使用内存="+monitorInfo.getMaxMemory()); System.out.println("操作系统="+monitorInfo.getOsName()); System.out.println("总的物理内存="+monitorInfo.getTotalMemorySize()+"kb"); System.out.println("剩余的物理内存="+monitorInfo.getFreeMemory()+"kb"); System.out.println("已使用的物理内存="+monitorInfo.getUsedMemory()+"kb"); System.out.println("线程总数="+monitorInfo.getTotalThread()+"kb"); } }
该实现类中需要用到一个自己编写byte的工具类,该类的代码如下所示:
packagecom.amgkaka.performance; /***//** *byte操作类. *@authoramg*@version1.0 *Creationdate:2008-4-30-下午04:57:23 */ publicclassBytes{ /***//** *由于String.subString对汉字处理存在问题(把一个汉字视为一个字节),因此在 *包含汉字的字符串时存在隐患,现调整如下: *@paramsrc要截取的字符串 *@paramstart_idx开始坐标(包括该坐标) *@paramend_idx截止坐标(包括该坐标) *@return */ publicstaticStringsubstring(Stringsrc,intstart_idx,intend_idx){ byte[]b=src.getBytes(); Stringtgt=""; for(inti=start_idx;i<=end_idx;i++){ tgt+=(char)b[i]; } returntgt; } }
运行下MonitorBeanImpl类,读者将会看到当前的内存、cpu利用率等信息。
PS:得到局域网内所有主机名的方法
importjava.net.InetAddress; importjava.net.UnknownHostException; publicclassA{ staticpublicvoidmain(String[]args){ try{ //通过主机名称得到IP地址 InetAddressaddress=InetAddress.getByName("192.168.9.148"); System.out.println("192.168.9.148"+":"+address.getHostAddress()); //通过IP得到主机名称 Stringips="192.168.9.",ip; InetAddressaddip; for(inti=148;i<255;i++){ ip=ips+i; addip=InetAddress.getByName(ip); System.out.println(ip+":"+addip.getHostName()); } } catch(UnknownHostExceptionuhe){ System.err.println("Unabletofind:"+"192.168.9.148"); } } }