Khi nhận sự kiện JVMTI cho Thu gom rác, JVM bị dừng kỹ thuật nên không thể gọi lại trình nghe Java qua JNI .... tác nhân này in ra thời gian tại GC bắt đầu và kết thúc với độ phân giải cao hơn tiết GC trên Sun JVM.
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include "jvmti.h"
void printGCTime(const char* type) {
struct timeval tv;
gettimeofday(&tv, NULL);
struct tm localTime;
localtime_r(&tv.tv_sec, &localTime);
char *startTime = calloc(1, 128);
strftime(startTime, (size_t) 128, "%a %b %d %Y %H:%M:%S", &localTime);
fprintf(stderr, "GC %s: %s.%06d\n", type, startTime, (int)tv.tv_usec);
fflush(stderr);
if(startTime) free(startTime);
}
void JNICALL
garbageCollectionStart(jvmtiEnv *jvmti_env) {
printGCTime("Start ");
}
void JNICALL
garbageCollectionFinish(jvmtiEnv *jvmti_env) {
printGCTime("Finish");
}
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM * jvm, char *options, void *reserved)
{
jvmtiEnv *jvmti_env;
jint returnCode = (*jvm)->GetEnv(jvm, (void **) &jvmti_env,
JVMTI_VERSION_1_0);
if (returnCode != JNI_OK)
{
fprintf(stderr,
"The version of JVMTI requested (1.0) is not supported by this JVM.\n");
return JVMTI_ERROR_UNSUPPORTED_VERSION;
}
jvmtiCapabilities *requiredCapabilities;
requiredCapabilities = (jvmtiCapabilities*) calloc(1, sizeof(jvmtiCapabilities));
if (!requiredCapabilities)
{
fprintf(stderr, "Unable to allocate memory\n");
return JVMTI_ERROR_OUT_OF_MEMORY;
}
requiredCapabilities->can_generate_garbage_collection_events = 1;
if (returnCode != JNI_OK)
{
fprintf(stderr, "C:\tJVM does not have the required capabilities (%d)\n",
returnCode);
exit(-1);
}
returnCode = (*jvmti_env)->AddCapabilities(jvmti_env, requiredCapabilities);
jvmtiEventCallbacks *eventCallbacks;
eventCallbacks = calloc(1, sizeof(jvmtiEventCallbacks));
if (!eventCallbacks)
{
fprintf(stderr, "Unable to allocate memory\n");
return JVMTI_ERROR_OUT_OF_MEMORY;
}
eventCallbacks->GarbageCollectionStart = &garbageCollectionStart;
eventCallbacks->GarbageCollectionFinish = &garbageCollectionFinish;
returnCode = (*jvmti_env)->SetEventCallbacks(jvmti_env,
eventCallbacks, (jint) sizeof(*eventCallbacks));
if (returnCode != JNI_OK)
{
fprintf(stderr, "C:\tError setting event callbacks (%d)\n",
returnCode);
exit(-1);
}
returnCode = (*jvmti_env)->SetEventNotificationMode(
jvmti_env, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_START, (jthread) NULL);
if (returnCode != JNI_OK)
{
fprintf(
stderr,
"C:\tJVM does not have the required capabilities, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_START (%d)\n",
returnCode);
exit(-1);
}
returnCode = (*jvmti_env)->SetEventNotificationMode(
jvmti_env, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, (jthread) NULL);
if (returnCode != JNI_OK)
{
fprintf(
stderr,
"C:\tJVM does not have the required capabilities, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH (%d)\n",
returnCode);
exit(-1);
}
if(requiredCapabilities) free(requiredCapabilities);
if(eventCallbacks) free(eventCallbacks);
return JVMTI_ERROR_NONE;
}
Lý tưởng nhất, một nhà phát triển không cần phải quan tâm khi GC xảy ra. Bạn có thể thực hiện một số thiết lập trong các đối số JVM. Chỉ vì tò mò, bạn đang cố gắng làm gì? Có thể có một sự kiện tốt hơn để đăng ký. – Jay
@Jay, chúng ta không sống trong một thế giới lý tưởng. Nếu bạn thực sự quan tâm đến dịch vụ của bạn làm việc, bạn có thể muốn báo động khi thu gom rác bắt đầu xảy ra quá thường xuyên vì nó có thể là một dấu hiệu của vấn đề. – tster
Câu hỏi hay. Nó sẽ tốt đẹp nếu GC thông báo có thể được tích hợp với một cân bằng tải để tránh gửi lưu lượng truy cập đến thể hiện trong GC. –