快速业务通道

基于JVMTI实现Java线程的监控 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-19
苏醒,这个即将苏醒的线程将在某个监视器空闲的时刻获取该监视器,并执行该监视区域代码,具体哪个线程被唤醒视虚拟机的实现方式而定。notifyAll() 方法会将等待集中的所有线程标记为即将苏醒,并接受虚拟机的调度。一个线程只有在它已经持有监视器时才能执行 wait() 方法,并且它只能通过再次成为监视器的持有者才能离开等待集。

图 4. Java 线程的同步机制

根据上述对 Java 线程同步机制的分析,如果能够在执行 wait()/notify()/notifyAll() 方法的前后分别获取其监视器等待集的状态快照并加以比较,就可以得出是哪个或者是哪些线程被唤醒,而这些线程就是这次隐式线程切换的被操作线程。这样,就可以确定线程切换的三元组 < 操作线程,动作,被操作线程 > 信息。

此外,由于一个线程可能同时拥有多个对象监视器,因此必须对每个监视器上的等待集进行分析,以确定当前执行的 wait()/notify()/notifyAll() 方法所真正作用的监视器。

基于JVMTI实现Java线程的监控(4)

时间:2011-02-06 IBM 李凌

实现 Java 线程监控代理

本节介绍了如何依据 Java 线程切换监控模型,实现 Java 线程监控代理(Agent)。

线程监控代理是一个基于 JVMTI 的 C 语言实现,它可以从虚拟机运行时实例中捕获运行中的 Java 应用程序的线程切换信息,同时不影响该程序的运行。

初始化监控代理

首先,监控代理必须包括一个 JVMTI 的头文件,主要代码片段如清单 1 所示。该头文件包含 JVMTI 必须的一些定义,通常它存在于 JDK 安装目录的 include 目录下。

其次,需要对代理进行初始化,这个工作由 Agent_OnLoad() 方法完成。这个方法主要用于在初始化 Java 虚拟机之前设置所需的功能(Capabilities)、注册事件通知(Event Notification)和指定事件回调函数(Callback Method)。其中,GetEnv() 方法用于获取当前的虚拟机运行环境;AddCapabilities() 方法用于设置线程监控代理所需要的功能,包括方法的调用和返回事件、访问方法局部变量、获取对象或线程拥有的监视器信息;SetEventNotificationMode() 方法用于捕获每个实例方法的调用和返回的事件通知;SetEventCallbacks() 方法用于注册相应的方法进入回调函数和方法退出回调函数。

清单 1. 初始化 Agent include "jvmti.h"  JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {   jvm->GetEnv((void **) &gb_jvmti, JVMTI_VERSION_1_0);   gb_capa.can_generate_method_exit_events = 1;   gb_capa.can_access_local_variables=1;   gb_capa.can_get_monitor_info=1;   gb_jvmti->AddCapabilities(&gb_capa);   callbacks.MethodEntry = &callbackMethodEntry;   callbacks.MethodExit = &callbackMethodExit;   gb_jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));   gb_jvmti->SetEventNotificationMode(JVMTI_ENABLE,JVMTI_EVENT_METHOD_ENTRY,NULL);   gb_jvmti->SetEventNotificationMode(JVMTI_ENABLE,JVMTI_EVENT_METHOD_EXIT,NULL);   return JNI_OK; }

监控显式线程切换

显式线程切换的监控通过 callbackMethodEntry() 回调方法完成,主要代码片段如清单 2 所示。该回调方法使用 RawMonitorEntry() 和 RawMonitorExit() 方法设定原始监视器的监视区域,监视引起显式线程切换的线程方法,例如 start()、interrupt()、join()、resume() 等。

当上述某个线程方法即将被调用时,先用 GetObjectHashCode() 方法计算当前操作线程的哈希值,籍此唯一标识这个线程对象;然后使用 GetLocalObject() 方法获取操作线程 Java 栈中当前方法

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号