频道直达 - 学院 - 下载 - 交易 - 特效 - 字库 - 手册 -排名-工具- 繁體
网页教学网站开发 设为首页
加入收藏
联系我们
建站搜索: 常用广告代码   用户注册 | 用户登陆
您当前的位置:中国建站之家 -> 网站开发设计技术教程 -> JavaScript教程 -> 在Java应用程序中使用JNI来监视CPU详解

在Java应用程序中使用JNI来监视CPU详解

作者:未知  来源:www.jz123.cn  发布时间:2007-7-21 7:37:06  发布人:圈圈

减小字体 增大字体

怎样在Java中得到CPU的使用情况呢?这儿同时有一个好消息和一个坏消息。

坏消息是不能使用纯Java的方法得到CPU的使用。没有这方面的直接的API。一个建议的替代方法是通过Runtime.exec()确定JVM的进程ID(PID),调用外部的、平台相关的命令,例如ps,然后在运行结果中解析出感兴趣的PID。但是,这种方法并不理想。

好消息是,可以采用一个更为可靠的方案:跳出Java,写几行C代码,然后通过JNI进行整合。下面我将向你展示编写一个Win32平台的简单的JNI库是多么简单。

一般来说,JNI有点复杂。但是,如果你仅仅单向调用--从Java调用本地代码,并且仅使用基本型进行通讯--事情还是很简单的。有许多JNI方面的学习资料,所以这儿就不介绍JNI的基础了。仅介绍实现步骤。

一、在Java中声明JNI方法

开始,创建一个声明了本地方法的类com.vladium.utils.SystemInformation,该方法返回当前进程已使用的CPU的毫秒数。

public staticnative long getProcessCPUTime();

使用JDK内置的javah工具产生将来本地代码实现使用的C头。

JNIEXPORT jlong JNICALL

Java_com_vladium_utils_SystemInformation_getProcessCPUTime (JNIEnv * env, jclass cls)

二、本地方法实现

在大多数的Win32平台上,该方法可以使用GetProcessTimes()系统调用实现,差不多仅需要3行代码就可以了:

JNIEXPORT jlong JNICALL 
Java_com_vladium_utils_SystemInformation_getProcessCPUTime(JNIEnv * env, jclass cls) 
{ 
 FILETIME creationTime, exitTime, kernelTime, userTime; 
     
 GetProcessTimes (s_currentProcess, & creationTime, & exitTime, & kernelTime, 
& userTime); 
  
 return (jlong) ((fileTimeToInt64 (& kernelTime) + fileTimeToInt64 (& userTime)) / 
(s_numberOfProcessors * 10000)); 
}

该方法首先累加用于执行当前进程的核心和用户代码耗费的时间,除以处理器的数目,并把结果转换到毫秒。fileTimeToInt64()是一个辅助函数,用于把FILETIME结构的数据转换为64位的整数。s_currentProcess 和 s_numberOfProcessors是全局变量,当JVM装载本地库时即初始化。

static HANDLE s_currentProcess; 
static int s_numberOfProcessors; 
  
JNIEXPORT jint JNICALL 
JNI_OnLoad (JavaVM * vm, void * reserved) 
{ 
    SYSTEM_INFO systemInfo; 
         
    s_currentProcess = GetCurrentProcess (); 
  
    GetSystemInfo (& systemInfo); 
    s_numberOfProcessors = systemInfo.dwNumberOfProcessors; 
  
    return JNI_VERSION_1_2; 
}

注意,如果你在UNIX平台上实现getProcessCPUTime(),你应该以getrusage系统调用开始。

三、调用本地方法

回到Java中,在SystemInformation类中,装载本地库(silib.dll on Win32)最好通过静态初始化代码块完成。

private static final String SILIB = "silib"; 
     
    static 
    { 
        try 
        { 
            System.loadLibrary (SILIB); 
        } 
        catch (UnsatisfiedLinkError e) 
        { 
        System.out.println ("native lib '" + SILIB + "' not found 
in 'java.library.path': " 
            + System.getProperty ("java.library.path")); 
             
            throw e; // re-throw 
        } 
    }

注意,getProcessCPUTime()返回自JVM进程创建以来使用的CPU时间。就这个数据本身而言,对于这儿并没有太多的用处。还需要更有用的Java方法来记录不同的时刻的数据快照(data snapshots),并报告任何两个时间点之间CPU的使用。

public static final class CPUUsageSnapshot 
    { 
        private CPUUsageSnapshot (long time, long CPUTime) 
        { 
            m_time = time; 
            m_CPUTime = CPUTime; 
        } 
         
        public final long m_time, m_CPUTime; 
         
    } // end of nested class 
     
    public static CPUUsageSnapshot makeCPUUsageSnapshot() 
    { 
    return new CPUUsageSnapshot(System.currentTimeMillis(),getProcessCPUTime ()); 
    } 
     
    public static double getProcessCPUUsage(CPUUsageSnapshot start, 
CPUUsageSnapshot end) 
   { 
    return ((double)(end.m_CPUTime - start.m_CPUTime)) / (end.m_time - start.m_time); 
   }

四、一个简单的CPU监视程序

“CPU监视API”基本就完成了!最后,创建了一个singleton的线程类CPUUsageThread,它自动地每过一个时间间隔(默认是0.5秒)就拍下一个数据快照,并报告给所有的CPU使用事件的监听者(Observer模式)。

public void run () 
    { 
        while (! isInterrupted ()) 
        { 
           final SystemInformation.CPUUsageSnapshot snapshot = 
SystemInformation.makeCPUUsageSnapshot (); 
            notifyListeners (snapshot); 
             
            try 
            { 
                sleep (sleepTime); 
            } 
            catch (InterruptedException e) 
            { 
                return; 
            } 
        } 
    }

CPUmon类是一个示例的监听器,仅简单地把CPU的使用情况打印输出到System.out。

public static void main (String [] args) throws Exception 
    { 
        if (args.length == 0) 
       throw new IllegalArgumentException ("usage: CPUmon <app_main_class> 
<app_main_args...>"); 
         
        CPUUsageThread monitor = CPUUsageThread.getCPUThreadUsageThread (); 
        CPUmon _this = new CPUmon (); 
         
        Class app = Class.forName (args [0]); 
        Method appmain = app.getMethod ("main", new Class [] {String[].class}); 
        String [] appargs = new String [args.length - 1]; 
        System.arraycopy (args, 1, appargs, 0, appargs.length); 
         
        monitor.addUsageEventListener (_this); 
        monitor.start (); 
        appmain.invoke (null, new Object [] {appargs}); 
    }

另外,为了能够在启动要监视的应用程序之前开始CPUUsageThread,CPUmon.main()包装了另一个Java主类。

作为演示,运行CPUmon和JDK1.3.1的SwingSet2示例程序(不要忘了把silib.dll安装到OS的PATH环境变量或者java.library.path系统属性所覆盖的路径下):

>java -Djava.library.path=. -cp silib.jar;(my JDK install dir)\demo\jfc\SwingSet2\SwingSet2.jar CPUmon SwingSet2

[PID: 339] CPU usage: 46.8%

[PID: 339] CPU usage: 51.4%

[PID: 339] CPU usage: 54.8%

(while loading, the demo uses nearly 100% of one of the two CPUs on my machine)

...

[PID: 339] CPU usage: 46.8%

[PID: 339] CPU usage: 0%

[PID: 339] CPU usage: 0%

(the demo finished loading all of its panels and is mostly idle)

...

[PID: 339] CPU usage: 100%

[PID: 339] CPU usage: 98.4%

[PID: 339] CPU usage: 97%

(I switched to the ColorChooserDemo panel which ran a CPU-intensive

animation that used both of my CPUs)

...

[PID: 339] CPU usage: 81.4%

[PID: 339] CPU usage: 50%

[PID: 339] CPU usage: 50%

(I used Windows NT Task Manager to adjust the CPU affinity for the

"java" process to use a single CPU)

...

当然,也可以通过任务管理器查看到CPU使用信息,这儿的要点是现在我们可以以编程方式记录该信息。对于长时间运行测试和服务器应用诊断程序,会派上用场。


将本文收藏到QQ书签与更多好友分享
[打 印]
[] [返回上一页] [收 藏]
∷相关文章评论∷    (评论内容只代表网友观点,与本站立场无关!) [更多评论...]
精彩推荐
热门文章
· 注册码大全二
· 注册码大全四
· 注册码大全一
· 要10G免费网络硬盘的请进..
· 通过google 赶快来赚美金..
· 注册码大全十
· 头像-qq头像(qq新头像)4..
· 让你轻松架设FTP服务器1..
· 注册码大全三
· 梦幻背景图片7
· 卡通动物图片6
· 网页制作素材-按钮素材2..
· 让你轻松架设FTP服务器5..
· 风景图片8
· 注册码大全九
· 让你轻松架设FTP服务器2..
关注此文读者还看过
· Karrigell 入门
· 金山老舵手遇上新课题 雷..
· MobiLink通过Oracle返回..
· 专家学者研究虚拟财产犯..
· 好了,我经过大家的支持..
· 第八节:模板运用之借鉴..
· 动画片常用的开场镜头
· 利用Yahoo! Search API开..
· ASP系列讲座(十一)Act..
· 2006年10大变态站名网站..
· 什么样的文章长度有利于..
· PHP语句中or的用法
· 无组件实现文件上传/下载..
· ASP漏洞及安全建议(3)
· AS基础精典教程 第六章 ..
· 数字小写到英文大写的转..
相关文章
· FCKeditor编辑器在JAVA中的..
· 在Javascript中为String对象..
关于本站 - 网站帮助 - 广告合作 - 下载声明 - 友情连接 - 网站地图 - 人才招聘
网站合作、内容监督、商务咨询:QQ: 9576619
Copyright ? 2005--2008 中国建站之家版权所有
粤ICP备05092265号