受jvmti对象分配回调行为困扰 [英] Perplexed by jvmti object allocation callback behavior

查看:285
本文介绍了受jvmti对象分配回调行为困扰的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以向我解释,当jvm分配一些Java对象而不分配其他Java对象时,为什么我可以得到回调吗?这是我在做什么:

Can anybody explain to me why can I get a callback when jvm allocates some java objects, but not others? Here is what I am doing:

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中确实存在该类的一个实例.有什么想法吗?

When I examine the file that I create, I do not see the classes that I am interested in, although I know they are there and NetBeans tells me there is exactly one instance of that class in the jvm. Any thoughts???

Nikita

推荐答案

出于性能原因,JVMTI仅支持无法通过字节码检测(BCI)检测到的对象的分配事件,如JVMTI VMObjectAlloc事件文档中所述.这意味着该事件将不会为大多数对象分配触发.我假设您缺少的分配属于该类别.

For performance reasons, the JVMTI only supports allocation events for objects that cannot be detected through bytecode instrumentation (BCI), as explained in the JVMTI VMObjectAlloc event documentation. This means that the event will not be triggered for most object allocations. I assume that the allocations you are missing fall within that category.

幸运的是,使用BCI截取所有对象分配并不是很困难. HeapTracker 该演示准确地说明了如何使用 java_crw_demo 拦截JVMTI代理中的所有对象分配. VMObjectAlloc事件.

Fortunately, it's not really too difficult to intercept all object allocations using BCI. The HeapTracker demo illustrates precisely how to intercept all object allocations in a JVMTI agent using java_crw_demo in addition to the VMObjectAlloc events.

这篇关于受jvmti对象分配回调行为困扰的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆