探索JVM运行状态的利器—JVMPI,HPROF

1.什么是JVMPIJava 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 <jvmpi.h>

//1.>cl -LDd -Zi -<place w:st="on">I.</place> -IC:\j2sdk<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.2</chsdate>_10\include -IC

// :\j2sdk<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.2</chsdate>_10\include\win32 -Tp.\jvmtrace.c -o jvmtrace.dll

//2.>copy jvmtrace.dll C:\j2sdk<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.2</chsdate>_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 -<place w:st="on">I.</place> -IC:\j2sdk<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.2</chsdate>_10\include -IC

:\j2sdk<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.2</chsdate>_10\include\win32 -Tp.\jvmtrace.c -o jvmtrace.dll

拷贝jvmtrace.dllJAVA_HOME\bin

>copy jvmtrace.dll C:\j2sdk<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.2</chsdate>_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.

2HPROF又什么是?HPROFJ2SE自带的一个简单的profiler agent 他是一个动态链接库文件,监控CPU的使用率,Heap分配情况等。将这些信息输出到文件或到socket

java –Xrunhprof ToBeProfiledClass [:help]|[:=, ...]

例如:

>java -Xrunhprof:heap=all org.colimas.jni.test.JniTest

在当前目录会生成java.hprof.txt文件。文件内记载了JVM运行时Heap的运行情况。

你可能感兴趣的:(jvm,thread,c,J2SE,jni)