探索JVM运行状态的利器JVMPI,HPROF
1.什么是JVMPI?Java Virtual Machine Profiler Interface。参考
http://java.sun.com/j2se/1.4.2/docs/guide/jvmpi/jvmpi.html#overview
JVMPI可以做什么?它可以监控VM发生的各种事件。例如当JVM创建,关闭,Java类被加载,创建对象,或GC回收,等37种事件。既然是接口自然就是有一个头文件,[JAVA_HOME]\include\jvmpi.h。您可以开发自己的Profiler监控Java VM的发生的各种事件。
下面是我编写的使用JVMPI的例子,输出结果说明了为了运行一个Java类,JVM需要做的各种操作。
#include
//1.>cl -LDd -Zi -I. -IC:\j2sdk1.4.2_10\include -IC
// :\j2sdk1.4.2_10\include\win32 -Tp.\jvmtrace.c -o jvmtrace.dll
//2.>copy jvmtrace.dll C:\j2sdk1.4.2_10\bin\
//3.>java -Xrunjvmtrace org.colimas.jni.test.JniTest
//jvmpi interface 全局指针
static JVMPI_Interface *jvmpi_interface;
//时间通知处理函数
void notifyEvent(JVMPI_Event *event) {
switch(event->event_type) {
/*非常可怕的输出,好奇就试试。
case JVMPI_EVENT_CLASS_LOAD:
fprintf(stderr, "trace> Class Load : %s\n", event->u.class_load.class_name);
break;*/
case JVMPI_EVENT_ARENA_DELETE :
fprintf(stderr, "trace> The heap arena :%d is deleted.\n", event->u.delete_arena.arena_id);
break;
case JVMPI_EVENT_ARENA_NEW :
fprintf(stderr, "trace> The heap arena %s:%d is created.\n",
event->u.new_arena.arena_name,
event->u.new_arena.arena_id);
break;
case JVMPI_EVENT_GC_FINISH :
fprintf(stderr, "trace> GC is finished. Used object:%d, space:%d, total object space:%d.\n",
event->u.gc_info.used_objects,
event->u.gc_info.used_object_space,
event->u.gc_info.total_object_space);
break;
case JVMPI_EVENT_GC_START :
fprintf(stderr, "trace>GC is started.\n");
break;
case JVMPI_EVENT_HEAP_DUMP :
fprintf(stderr, "trace> The heap dump begin %s,end %s.\n",
event->u.heap_dump.begin,
event->u.heap_dump.end);
break;
case JVMPI_EVENT_JVM_INIT_DONE :
fprintf(stderr, "trace> JVM initialization is done.\n");
break;
case JVMPI_EVENT_JVM_SHUT_DOWN :
fprintf(stderr, "trace> JVM is shutting down.\n");
break;
case JVMPI_EVENT_THREAD_END :
fprintf(stderr, "trace> A thread ends.\n");
break;
case JVMPI_EVENT_THREAD_START :
fprintf(stderr, "trace> The thread %s begins whose group is %s, parent is %s.\n",
event->u.thread_start.thread_name ,
event->u.thread_start.group_name,
event->u.thread_start.parent_name);
break;
}
}
// profiler agent entry point
extern "C" {
JNIEXPORT jint JNICALL JVM_OnLoad(JavaVM *jvm, char *options, void *reserved) {
fprintf(stderr, "trace> initializing ..... \n");
// get jvmpi interface pointer
if ((jvm->GetEnv((void **)&jvmpi_interface, JVMPI_VERSION_1)) < 0) {
fprintf(stderr, "trace> error in obtaining jvmpi interface pointer\n");
return JNI_ERR;
}
// initialize jvmpi interface
jvmpi_interface->NotifyEvent = notifyEvent;
// enabling class load event notification
//jvmpi_interface->EnableEvent(JVMPI_EVENT_CLASS_LOAD, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_ARENA_DELETE, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_ARENA_NEW, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_GC_FINISH, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_GC_START, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_HEAP_DUMP, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_JVM_INIT_DONE, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_JVM_SHUT_DOWN, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_THREAD_END, NULL);
jvmpi_interface->EnableEvent(JVMPI_EVENT_THREAD_START, NULL);
fprintf(stderr, "trace> .... ok, dumping...\n");
if (jvmpi_interface->RequestEvent(JVMPI_EVENT_HEAP_DUMP,NULL)<0)
{
fprintf(stderr, "trace> error in obtaining jvmpi interface pointer\n");
return JNI_ERR;
}
fprintf(stderr, "trace> .... end\n\n");
return JNI_OK;
}
}
编译
>cl -LDd -Zi -I. -IC:\j2sdk1.4.2_10\include -IC
:\j2sdk1.4.2_10\include\win32 -Tp.\jvmtrace.c -o jvmtrace.dll
拷贝jvmtrace.dll到JAVA_HOME\bin
>copy jvmtrace.dll C:\j2sdk1.4.2_10\bin\
运行
>java -Xrunjvmtrace org.colimas.jni.test.JniTest
结果
trace> initializing .....
trace> .... ok, dumping...
trace> .... end
trace> The thread Finalizer begins whose group is system, parent is (null).
trace> The thread Reference Handler begins whose group is system, parent is (nul
l).
trace> The thread main begins whose group is main, parent is system.
trace> JVM initialization is done.
trace> The thread Signal Dispatcher begins whose group is system, parent is (nul
l).
hello JVM
trace> A thread ends.
trace> The thread DestroyJavaVM begins whose group is main, parent is system.
trace> A thread ends.
trace> JVM is shutting down.
2.HPROF又什么是?HPROF是J2SE自带的一个简单的profiler agent。 他是一个动态链接库文件,监控CPU的使用率,Heap分配情况等。将这些信息输出到文件或到socket。
java –Xrunhprof ToBeProfiledClass [:help]|[:=, ...]
例如:
>java -Xrunhprof:heap=all org.colimas.jni.test.JniTest
在当前目录会生成java.hprof.txt文件。文件内记载了JVM运行时Heap的运行情况。