gpt4 book ai didi

java - 有没有办法使用 JVMTI 生成定期的 java 线程转储?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:55:43 24 4
gpt4 key购买 nike

在 java 中有多种生成线程转储的方法。

我想使用 JVMTI (C API)来生成它,以评估它对正在运行的 JVM 的性能影响。 (我知道 jstack 和 JMX ;这个问题通常不是关于获取线程转储,而是关于使用 JVMTI API)。

我的代码基于 this blog post .在那里,java 代理附加到 SIGQUIT 信号。我想避免这种情况,因为这与 JVM 用于将线程转储写入标准输出的信号相同。我想避免这种口是心非。

换句话说,我想附加到不同的信号,或者找到一种方法让代理定期生成线程转储。

最佳答案

In there, the java agent attaches to the SIGQUIT signal. I'd like to avoid that, because that is the same signal that the JVM uses in order to write a thread dump to stdout. I want to avoid that duplicity.

只需从您的代码中删除以下片段

/* Set callbacks and enable event notifications */
memset(&callbacks, 0, sizeof(callbacks));
callbacks.DataDumpRequest = &dumpThreadInfo;
err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
CHECK_JVMTI_ERROR(jvmti, err);
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
CHECK_JVMTI_ERROR(jvmti, err);

I'd like to either attach to a different signal

Here is论文,有点旧,但信息应该还是相关的。

只是一个如何进行信号处理的示例

import sun.misc.Signal;
import sun.misc.SignalHandler;

public class ThreadDumpSignalHandler implements SignalHandler {
private volatile SignalHandler old;
private ThreadDumpSignalHandler() {

}
public static void register(String sigName) {
ThreadDumpSignalHandler h = new ThreadDumpSignalHandler();
h.old = Signal.handle(new Signal(sigName), h)
}
public void handle(Signal sig) {
threadDump();

if(old != null && old != SIG_DFL && old != SIG_IGN) {
old.handle(sig);
}
}
// call your own threadDump native method.
// note that in the implementation of this method you are able to access jvmtiEnv from *gdata (see below)
private native void threadDump();
}

ThreadDumpSignalHandler.register("INT");

因为你可以编写完全原生的信号处理程序(请注意我还没有测试过它,这只是一个应该可行的想法)

static sighandler_t old_handler;
static void thread_dump_handler(int signum) {
if(gdata && gdata->jvmti) {
... get thread dump
}

if(old_handler) {
old_handler(signum);
}
}

JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
old_handler = signal(SIGINT, thread_dump_handler);

...
}

or find a way for the agent to generate a thread dump periodically.

在您的示例中有全局 *gdata

typedef struct {
/* JVMTI Environment */
jvmtiEnv *jvmti;
jboolean vm_is_started;
/* Data access Lock */
jrawMonitorID lock;
} GlobalAgentData;

static GlobalAgentData *gdata;

...所以,您可以随时从那里获取 jvmtiEnv(计时器回调等)

关于java - 有没有办法使用 JVMTI 生成定期的 java 线程转储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26795511/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com