示例#1
0
文件: jleaker.c 项目: jleaker/jleaker
/* Callback for JVMTI_EVENT_VM_DEATH */
static void JNICALL 
vmDeath(jvmtiEnv *jvmti, __UNUSED__ JNIEnv *env)
{
    /* Disable events and dump the heap information */
    enterAgentMonitor(jvmti); {

        gdata->vmDeathCalled = JNI_TRUE;

    } exitAgentMonitor(jvmti);
}
示例#2
0
文件: jleaker.c 项目: jleaker/jleaker
/* Callback for JVMTI_EVENT_VM_INIT */
static void JNICALL
vmInit(jvmtiEnv *jvmti, __UNUSED__ JNIEnv *env, __UNUSED__ jthread thread)
{
    enterAgentMonitor(jvmti); {
        /* Indicate VM has started */
        gdata->vmStarted = JNI_TRUE;
        startDumperThread();

    } exitAgentMonitor(jvmti);
}
/* Callback for JVMTI_EVENT_VM_INIT */
static void JNICALL
vmInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
{
    enterAgentMonitor(jvmti); {
        jvmtiError          err;

        err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
                            JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
        check_jvmti_error(jvmti, err, "set event notification");
    } exitAgentMonitor(jvmti);
}
/* Callback for JVMTI_EVENT_VM_DEATH */
static void JNICALL
vmDeath(jvmtiEnv *jvmti, JNIEnv *env)
{
    jvmtiError          err;

    /* Make sure everything has been garbage collected */
    err = (*jvmti)->ForceGarbageCollection(jvmti);
    check_jvmti_error(jvmti, err, "force garbage collection");

    /* Disable events and dump the heap information */
    enterAgentMonitor(jvmti); {
        err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_DISABLE,
                            JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
        check_jvmti_error(jvmti, err, "set event notification");

        dataDumpRequest(jvmti);

        gdata->vmDeathCalled = JNI_TRUE;
    } exitAgentMonitor(jvmti);
}
/* Callback for JVMTI_EVENT_DATA_DUMP_REQUEST (Ctrl-\ or at exit) */
static void JNICALL
dataDumpRequest(jvmtiEnv *jvmti)
{
    enterAgentMonitor(jvmti); {
        if ( !gdata->vmDeathCalled && !gdata->dumpInProgress ) {
            jvmtiHeapCallbacks heapCallbacks;
            ClassDetails      *details;
            jvmtiError         err;
            jclass            *classes;
            jint               totalCount;
            jint               count;
            jint               i;

            gdata->dumpInProgress = JNI_TRUE;

            /* Get all the loaded classes */
            err = (*jvmti)->GetLoadedClasses(jvmti, &count, &classes);
            check_jvmti_error(jvmti, err, "get loaded classes");

            /* Setup an area to hold details about these classes */
            details = (ClassDetails*)calloc(sizeof(ClassDetails), count);
            if ( details == NULL ) {
                fatal_error("ERROR: Ran out of malloc space\n");
            }
            for ( i = 0 ; i < count ; i++ ) {
                char *sig;

                /* Get and save the class signature */
                err = (*jvmti)->GetClassSignature(jvmti, classes[i], &sig, NULL);
                check_jvmti_error(jvmti, err, "get class signature");
                if ( sig == NULL ) {
                    fatal_error("ERROR: No class signature found\n");
                }
                details[i].signature = strdup(sig);
                deallocate(jvmti, sig);

                /* Tag this jclass */
                err = (*jvmti)->SetTag(jvmti, classes[i],
                                    (jlong)(ptrdiff_t)(void*)(&details[i]));
                check_jvmti_error(jvmti, err, "set object tag");
            }

            /* Iterate through the heap and count up uses of jclass */
            (void)memset(&heapCallbacks, 0, sizeof(heapCallbacks));
            heapCallbacks.heap_iteration_callback = &cbHeapObject;
            totalCount = 0;
            err = (*jvmti)->IterateThroughHeap(jvmti,
                       JVMTI_HEAP_FILTER_CLASS_UNTAGGED, NULL,
                       &heapCallbacks, (const void *)&totalCount);
            check_jvmti_error(jvmti, err, "iterate through heap");

            /* Remove tags */
            for ( i = 0 ; i < count ; i++ ) {
                /* Un-Tag this jclass */
                err = (*jvmti)->SetTag(jvmti, classes[i], (jlong)0);
                check_jvmti_error(jvmti, err, "set object tag");
            }

            /* Sort details by space used */
            qsort(details, count, sizeof(ClassDetails), &compareDetails);

            /* Print out sorted table */
            stdout_message("Heap View, Total of %d objects found.\n\n",
                         totalCount);

            stdout_message("Space      Count      Class Signature\n");
            stdout_message("---------- ---------- ----------------------\n");

            for ( i = 0 ; i < count ; i++ ) {
                if ( details[i].space == 0 || i > 20 ) {
                    break;
                }
                stdout_message("%10d %10d %s\n",
                    details[i].space, details[i].count, details[i].signature);
            }
            stdout_message("---------- ---------- ----------------------\n\n");

            /* Free up all allocated space */
            deallocate(jvmti, classes);
            for ( i = 0 ; i < count ; i++ ) {
                if ( details[i].signature != NULL ) {
                    free(details[i].signature);
                }
            }
            free(details);

            gdata->dumpInProgress = JNI_FALSE;
        }
    } exitAgentMonitor(jvmti);
}