WEB开发网
开发学院WEB开发Jsp java不用jni,也可以获得当前系统性能信息 阅读

java不用jni,也可以获得当前系统性能信息

 2009-10-09 20:54:16 来源:WEB开发网   
核心提示:最近做个项目,就是要取得cpu占有率等等的系统信息,java不用jni,也可以获得当前系统性能信息,一开始以为要用动态链接库了,但后来发现可以像下面这样做,因此在 * 包含汉字的字符串时存在隐患,现调整如下: * @param src 要截取的字符串 * @param start_idx 开始坐标(包括该坐标) * @

最近做个项目,就是要取得cpu占有率等等的系统信息,一开始以为要用动态链接库了,但后来发现可以像下面这样做,不去调用jni,这样省去了很多看新技术的时间o(∩_∩)o...

在java中,可以获得总的物理内存、剩余的物理内存、已使用的物理内存等信息,下面例子可以取得这些信息,并且获得在Windows下的内存使用率。
   首先编写一个MonitorInfoBean类,用来装载监控的一些信息,包括物理内存、剩余的物理内存、已使用的物理内存、内存使用率等字段,该类的代码如下:

Java代码 
package  com.amgkaka.performance; 
 
/** */ /** 
 * 监视信息的JavaBean类. 
 * @author  amg 
 * @version 1.0  
 * Creation date: 2008-4-25 - 上午10:37:00 
 */  
public  class  MonitorInfoBean { 
   /** */ /** 可使用内存. */  
   PRivate  long  totalMemory; 
   
   /** */ /** 剩余内存. */  
   private  long  freeMemory; 
   
   /** */ /** 最大可使用内存. */  
   private  long  maxMemory; 
   
   /** */ /** 操作系统. */  
   private  String osName; 
   
   /** */ /** 总的物理内存. */  
   private  long  totalMemorySize; 
   
   /** */ /** 剩余的物理内存. */  
   private  long  freePhysicalMemorySize; 
   
   /** */ /** 已使用的物理内存. */  
   private  long  usedMemory; 
   
   /** */ /** 线程总数. */  
   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; 
   } 
} 
package com.amgkaka.performance;

/** *//**
 * 监视信息的JavaBean类.
 * @author  amg
 * @version 1.0
 * Creation date: 2008-4-25 - 上午10:37:00
 */
public class MonitorInfoBean {
   /** *//** 可使用内存. */
   private long totalMemory;
  
   /** *//** 剩余内存. */
   private long freeMemory;
  
   /** *//** 最大可使用内存. */
   private long maxMemory;
  
   /** *//** 操作系统. */
   private String osName;
  
   /** *//** 总的物理内存. */
   private long totalMemorySize;
  
   /** *//** 剩余的物理内存. */
   private long freePhysicalMemorySize;
  
   /** *//** 已使用的物理内存. */
   private long usedMemory;
  
   /** *//** 线程总数. */
   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;
   }
}
接着编写一个获得当前的监控信息的接口,该类的代码如下所示:

Java代码 
package  com.amgkaka.performance; 
 
/** */ /** 
 * 获取系统信息的业务逻辑类接口. 
 * @author amg * @version 1.0  
 * Creation date: 2008-3-11 - 上午10:06:06 
 */  
public  interface  IMonitorService { 
   /** */ /** 
   * 获得当前的监控对象. 
   * @return 返回构造好的监控对象 
   * @throws Exception 
   * @author amgkaka 
   * Creation date: 2008-4-25 - 上午10:45:08 
   */  
   public  MonitorInfoBean getMonitorInfoBean()  throws  Exception; 
 
} 
package com.amgkaka.performance;

/** *//**
 * 获取系统信息的业务逻辑类接口.
 * @author amg * @version 1.0
 * Creation date: 2008-3-11 - 上午10:06:06
 */
public interface IMonitorService {
   /** *//**
   * 获得当前的监控对象.
   * @return 返回构造好的监控对象
   * @throws Exception
   * @author amgkaka
   * Creation date: 2008-4-25 - 上午10:45:08
   */
   public MonitorInfoBean getMonitorInfoBean() throws Exception;

}  该类的实现类MonitorServiceImpl如下所示:

Java代码 
package  com.amgkaka.performance; 
 
import  java.io.InputStreamReader; 
import  java.io.LineNumberReader; 
 
import  sun.management.ManagementFactory; 
 
import  com.sun.management.OperatingSystemMXBean; 
 
/** */ /** 
 * 获取系统信息的业务逻辑实现类. 
 * @author amg * @version 1.0 Creation date: 2008-3-11 - 上午10:06:06 
 */  
public  class  MonitorServiceImpl  implements  IMonitorService { 
   //可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了  
   private  static  final  int  CPUTIME =  5000 ; 
 
   private  static  final  int  PERCENT =  100 ; 
 
   private  static  final  int  FAULTLENGTH =  10 ; 
 
   /** */ /** 
   * 获得当前的监控对象. 
   * @return 返回构造好的监控对象 
   * @throws Exception 
   * @author amg   * Creation date: 2008-4-25 - 上午10:45:08 
   */  
   public  MonitorInfoBean 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 = this .getCpuRatioForWindows(); 
     } 
     
     // 构造返回对象  
     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" ; 
       // 取进程信息  
       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 ; 
         } 
         // 字段出现顺序: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("可使用内存="  + 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" ); 
   } 
} 
package com.amgkaka.performance;

import java.io.InputStreamReader;
import java.io.LineNumberReader;

import sun.management.ManagementFactory;

import com.sun.management.OperatingSystemMXBean;

/** *//**
 * 获取系统信息的业务逻辑实现类.
 * @author amg * @version 1.0 Creation date: 2008-3-11 - 上午10:06:06
 */
public class MonitorServiceImpl implements IMonitorService {
   //可以设置长些,防止读到运行此次系统检查时的cpu占用率,就不准了
   private static final int CPUTIME = 5000;

   private static final int PERCENT = 100;

   private static final int FAULTLENGTH = 10;

   /** *//**
   * 获得当前的监控对象.
   * @return 返回构造好的监控对象
   * @throws Exception
   * @author amg   * Creation date: 2008-4-25 - 上午10:45:08
   */
   public MonitorInfoBean 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 = this.getCpuRatioForWindows();
     }
    
     // 构造返回对象
     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";
       // 取进程信息
       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;
         }
         // 字段出现顺序: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("可使用内存=" + 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的工具类,该类的代码如下所示:

Java代码 
package  com.amgkaka.performance; 
 
/** */ /** 
 * byte操作类. 
 * @author amg * @version 1.0  
 * Creation date: 2008-4-30 - 下午04:57:23 
 */  
public  class  Bytes { 
   /** */ /** 
   * 由于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; 
   } 
} 
package com.amgkaka.performance;

/** *//**
 * byte操作类.
 * @author amg * @version 1.0
 * Creation date: 2008-4-30 - 下午04:57:23
 */
public class Bytes {
   /** *//**
   * 由于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;
   }
}
运行下MonitorBeanImpl类,读者将会看到当前的内存、cpu利用率等信息。

Tags:java 不用 jni

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接