Jvm选项-PrintNMTStatistics将信息保存到文件中



我使用-XX:+PrintNMTStatistics来获取内存状态。

但不能存储在文件中

那么我如何将这些信息保存到文件中呢?

-XX:+PrintNMTStatistics打印到JVM控制台,这是不可更改的。

但是,可以创建自己的实用程序,在JVM退出之前将NMT统计信息转储到文件中。

这个想法类似于这个答案:创建一个JVMTI代理,它拦截VMDeath事件,然后使用JVM管理接口调用VM.native_memory诊断命令。

#include <jvmti.h>
#include <stdio.h>
#include <string.h>
static const char* filename;
extern void* JNICALL JVM_GetManagement(jint version);
static void* get_management_func() {
void** jmm;
if ((jmm = JVM_GetManagement(0x20010000)) != NULL) return jmm[39];
if ((jmm = JVM_GetManagement(0x20020000)) != NULL) return jmm[37];
if ((jmm = JVM_GetManagement(0x20030000)) != NULL) return jmm[38];
return NULL;
}
static void save_to_file(const char* result_str) {
FILE* f = fopen(filename, "w");
if (f != NULL) {
fprintf(f, "%s", result_str);
fclose(f);
} else {
fprintf(stderr, "%s", result_str);
}
}
void JNICALL VMDeath(jvmtiEnv* jvmti, JNIEnv* env) {
jstring (JNICALL *func)(JNIEnv*, jstring) = get_management_func();
if (func == NULL) {
fprintf(stderr, "JMM interface is not supported on this JVMn");
return;
}
jstring cmd = (*env)->NewStringUTF(env, "VM.native_memory summary");
jstring result = func(env, cmd);
if (result != NULL) {
const char* result_str = (*env)->GetStringUTFChars(env, result, NULL);
save_to_file(result_str);
(*env)->ReleaseStringUTFChars(env, result, result_str);
}
}
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
filename = options != NULL ? strdup(options) : "";
jvmtiEnv* jvmti;
(*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0);
jvmtiEventCallbacks callbacks = {0};
callbacks.VMDeath = VMDeath;
(*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
(*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
return 0;
}

将上述代码保存到nmtdump.c并编译:

gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -fPIC -olibnmtdump.so nmtdump.c

然后使用我们的代理运行Java:

java -XX:NativeMemoryTracking=summary -agentpath:/path/to/libnmtdump.so=dump.txt ...

现在,当JVM退出时,它将把NMT报告保存到dump.txt

最新更新