2012-03-25 4 views
1

Может кто-нибудь объяснить мне, почему я могу получить обратный вызов, когда jvm выделяет некоторые java-объекты, но не другие? Вот что я делаю:Недоумение от поведения обратного вызова объекта jvmti

static jvmtiCapabilities capa; 
static jvmtiEnv*   jvmti     = NULL; 
static const char*   fileName    = "C:\\temp\\ObjectInitCallbackDump.txt"; 
static ofstream    outFileStream; 

void JNICALL callbackObjectAllocation (jvmtiEnv* jvmti_env, 
             JNIEnv*  jni_env, 
             jthread  thread, 
             jobject  object, 
             jclass  object_klass, 
             jlong  size   ) 
{ 
    char*  generic_ptr_class; 
    char*  class_name; 
    jvmtiError error; 

    error = jvmti_env->GetClassSignature(object_klass, &class_name, &generic_ptr_class); 
    if (check_jvmti_error(jvmti_env, error, "Failed to get class signature")) { 
     return; 
    } 
    outFileStream << class_name << std::endl; 
} 

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { 
    jint    result; 
    jvmtiError   error; 
    jvmtiEventCallbacks callbacks; 

    outFileStream.open(fileName,ios::trunc); 

    result = jvm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_1); 
    if (result != JNI_OK || jvmti == NULL) { 
     printf("error\n"); 
     return JNI_ERR; 
    } else { 
     printf("loaded agent\n"); 
    } 

    (void) memset(&capa, 0, sizeof(jvmtiCapabilities)); 
    capa.can_generate_vm_object_alloc_events  = 1; 

    error = jvmti->AddCapabilities(&capa); 
    if (check_jvmti_error(jvmti, error, "Unable to set capabilities") != JNI_OK) { 
     return JNI_ERR; 
    } 

    (void) memset(&callbacks, 0, sizeof(callbacks)); 
    callbacks.VMObjectAlloc   = &callbackObjectAllocation; 

    error = jvmti->SetEventCallbacks(&callbacks, (jint) sizeof(callbacks)); 
    if (check_jvmti_error(jvmti, error, "Unable to set callbacks") != JNI_OK) { 
     return JNI_ERR; 
    } 

    error = jvmti->SetEventNotificationMode( JVMTI_ENABLE, 
               JVMTI_EVENT_VM_OBJECT_ALLOC, 
               (jthread) NULL); 
    if (check_jvmti_error(jvmti, error, 
      "Unable to set method entry notifications") != JNI_OK) { 
     return JNI_ERR; 
    } 

    return JNI_OK; 
} 

JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm) { 
    outFileStream.close(); 
} 

Когда я анализирую файл, который я создаю, я не вижу классы, которые я заинтересован в, хотя я знаю, что они там и NetBeans говорит мне, есть ровно один экземпляр этого класса в jvm. Есть предположения???

Nikita

ответ

8

По соображениям производительности JVMTI поддерживает только событие выделения для объектов, которые не могут быть обнаружены с помощью байткода приборов (BCI), как описано в JVMTI VMObjectAlloc документация по событиям. Это означает, что событие не будет инициировано для большинства распределений объектов. Я предполагаю, что выделенные вами ассигнования относятся к этой категории.

К счастью, это не слишком сложно перехватить все распределения объектов с помощью BCI. Демо-версия HeapTracker иллюстрирует то, как перехватывать все распределения объектов в агенте JVMTI, используя java_crw_demo в дополнение к событиям VMObjectAlloc.

0

Возможно, вы просто не нанесете на чек? Если это код, который вы фактически запускаете, у вас есть ошибка; вы пропустили; в конце объекта Вашего сравнение должна быть такой:

if (strcmp(class_name,"Ljavax/swing/JFrame;") == 0) { 
    printf("Got the sucker!!!"); 
} 
+0

Фактически я использую другую функцию, которая находит подстроку в заданной строке, но я даже изменил стратегию и сбросил каждый дескриптор класса, который я смог извлечь из callbackObjectAllocation в текстовый файл, а затем рассмотрел этот файл. Я использую что-то вроде 4 Мб текста с сотнями тысяч классов, но ни один из них меня не интересует, хотя я просто вижу их на экране. Итак, я совершенно озадачен, что делает некоторые объекты особенными, что их выделение вызывает это событие, а другие - не вызывать его. Есть предположения? –

+0

Я только что обновил список до более представительного примера. Надеюсь, кто-то может помочь. Мне в основном досадно, что в этом механизме я чего-то не понимаю. благодаря –