1

jvmが一部のJavaオブジェクトを割り当てたが、他のオブジェクトは割り当てないのに、なぜコールバックを取得できるのか、誰かに説明してもらえますか?これが私がしていることです:

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にそのクラスのインスタンスが1つだけあると言っています。何かご意見は???

ニキータ

4

2 に答える 2

9

VMObjectAlloc パフォーマンス上の理由から、JVMTIは、JVMTIイベントのドキュメントで説明されているように、バイトコードインストルメンテーション(BCI)では検出できないオブジェクトの割り当てイベントのみをサポートします。これは、ほとんどのオブジェクト割り当てでイベントがトリガーされないことを意味します。不足している割り当ては、そのカテゴリに含まれると思います。

幸い、BCIを使用してすべてのオブジェクト割り当てをインターセプトすることはそれほど難しくありません。HeapTrackerデモは、イベントに加えてjava_crw_demoを使用して、JVMTIエージェント内のすべてのオブジェクト割り当てをインターセプトする方法を正確に示していVMObjectAllocます。

于 2012-07-15T22:35:18.737 に答える
0

たぶんあなたはあなたのチェックを打っていないのですか?これが実際に実行するコードである場合は、バグがあります。あなたは逃した; オブジェクトの最後で、比較は次のようになります。

if (strcmp(class_name,"Ljavax/swing/JFrame;") == 0) {
    printf("Got the sucker!!!");
}
于 2012-03-25T19:14:13.970 に答える