Параметры Jvm - PrintNMTStatistics сохранить информацию в файл - PullRequest
2 голосов
/ 27 марта 2020

Я использую -XX:+PrintNMTStatistics для получения статуса памяти.

, но его нельзя сохранить в файле

, так как я могу сохранить эту информацию в файл?

1 Ответ

0 голосов
/ 29 марта 2020

-XX:+PrintNMTStatistics выводит на консоль JVM, и это нельзя изменить.

Однако можно создать собственную утилиту, которая будет выгружать статистику NMT в файл до выхода из JVM.

Идея похожа на этот ответ : создайте JVMTI агент, который перехватывает событие VMDeath, а затем использует интерфейс управления JVM для вызова VM.native_memory Diagnosti c команды.

#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 JVM\n");
        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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...