我部署了一个简单的JVMTI代理来测试字节码检测。我的策略是在RetransformClasses中调用CompiledMethodLoad函数,回调来调用ClassFileLoadHook。为此,我编写了以下代码:
err = (*jvmti)->GetMethodDeclaringClass(jvmti, method, &klass);
check_jvmti_error(jvmti, err, "Get Declaring Class");
err = (*jvmti)->RetransformClasses(jvmti, 1, &klass);
check_jvmti_error(jvmti, err, "Retransform class");这个函数通过调用ClassFileLoadHook事件正确地工作,但是当我只是在其中传递同一个类时,它会花费大量的时间。我的ClassFileLoadHook回调函数是空的。我在计算一个简单的矩阵乘法算法的时间。通过注释掉RetransformClasses函数,得到0.8 seconds顺序的执行时间。而仅仅编写这个函数就会将执行时间提高到15 seconds周围。
它应该承担那么多的开销,还是我做错了什么?
问候
代码:
static int x = 1;
void JNICALL
compiled_method_load(jvmtiEnv *jvmti, jmethodID method, jint code_size,
const void* code_addr, jint map_length, const jvmtiAddrLocationMap* map,
const void* compile_info) {
jvmtiError err;
jclass klass;
char* name = NULL;
char* signature = NULL;
char* generic_ptr = NULL;
err = (*jvmti)->RawMonitorEnter(jvmti, lock);
check_jvmti_error(jvmti, err, "raw monitor enter");
err = (*jvmti)->GetMethodName(jvmti, method, &name, &signature,
&generic_ptr);
check_jvmti_error(jvmti, err, "Get Method Name");
printf("\nCompiled method load event\n");
printf("Method name %s %s %s\n\n", name, signature,
generic_ptr == NULL ? "" : generic_ptr);
if (strstr(name, "main") != NULL && x == 1) {
x++;
err = (*jvmti)->GetMethodDeclaringClass(jvmti, method, &klass);
check_jvmti_error(jvmti, err, "Get Declaring Class");
err = (*jvmti)->RetransformClasses(jvmti, 1, &klass);
check_jvmti_error(jvmti, err, "Retransform class");
}
if (name != NULL) {
err = (*jvmti)->Deallocate(jvmti, (unsigned char*) name);
check_jvmti_error(jvmti, err, "deallocate name");
}
if (signature != NULL) {
err = (*jvmti)->Deallocate(jvmti, (unsigned char*) signature);
check_jvmti_error(jvmti, err, "deallocate signature");
}
if (generic_ptr != NULL) {
err = (*jvmti)->Deallocate(jvmti, (unsigned char*) generic_ptr);
check_jvmti_error(jvmti, err, "deallocate generic_ptr");
}
err = (*jvmti)->RawMonitorExit(jvmti, lock);
check_jvmti_error(jvmti, err, "raw monitor exit");
}发布于 2017-02-03 07:28:09
要回答我的问题:
不是的。我没做错什么。应该花那么多时间在头顶上。
--这是证据:
我用吉特沃特来了解这个问题。我分析了JIT调用后的ClassLoad时间检测和检测。在这两种情况下,我都使用相同的应用程序代码。
类加载时间仪表

执行时间:18秒左右。
JIT调用过程中的工具

执行时间:80秒左右。
结论
我们可以在这里清楚地看到,当我试图通过调用RetransformClasses -> CLassFileLoadHook序列在CompiledLoadEvent中对代码进行测试时,JIT简单地停止,然后就不会为我试图检测的函数被调用。之后,它甚至不进行OSR编译。我在这个回答中总结了JIT行为的原因。后续问题给出了这里。任何知道解决办法的人都是最欢迎回答的。
https://stackoverflow.com/questions/41327794
复制相似问题