"-6ren"> "-我正在尝试以编程方式执行强制 java 线程转储,就像命令 jstack -F -l 一样会做的。 我最好的尝试:我从 sun.jvm.hotspot.tools.JStack 创建了一个子类覆盖 -6ren">
gpt4 book ai didi

Java 以编程方式强制线程转储 - 如 "jstack -F -l "

转载 作者:行者123 更新时间:2023-11-30 11:07:52 24 4
gpt4 key购买 nike

我正在尝试以编程方式执行强制 java 线程转储,就像命令 jstack -F -l <PID> 一样会做的。

我最好的尝试:我从 sun.jvm.hotspot.tools.JStack 创建了一个子类覆盖 run()使用以下类似于 sun.jvm.hotspot.tools.JStack.run() 的代码但在最后一行调用 start(printstream)而不是 start() :

    StackTrace stacktrace = new StackTrace(mixedMode, concurrentLocks);

try {
Class<?> stacktraceTool = stacktrace.getClass().getSuperclass();

Method stacktraceSetAgent = stacktraceTool.getDeclaredMethod("setAgent", new Class<?>[] { BugSpotAgent.class });
stacktraceSetAgent.setAccessible(true);
stacktraceSetAgent.invoke(stacktrace, new Object[] { this.getAgent() });

Method stacktraceSetDebugeeType = stacktraceTool.getDeclaredMethod("setDebugeeType", new Class<?>[] { int.class });
stacktraceSetDebugeeType.setAccessible(true);
stacktraceSetDebugeeType.invoke(stacktrace, new Object[] { this.getDebugeeType() });

stacktrace.run(new PrintStream(this.targetFile));
}
catch (Exception e) {
e.printStackTrace(System.err);
}

问题:java.lang.RuntimeException: Attempt to initialize VM twice

因此我做了:

//reset stuff
VM.shutdown();

//clear observer list
Field f = VM.class.getDeclaredField("vmInitializedObservers");
f.setAccessible(true);
VM vmm = VM.getVM();
Object fo = f.get(vmm);
List folist = (List) fo;
folist.clear();

f = sun.jvm.hotspot.runtime.Threads.class.getDeclaredField("threadFactory");
f.setAccessible(true);
f.set(null, null);
f = sun.jvm.hotspot.runtime.Threads.class.getDeclaredField("threadListField");
f.setAccessible(true);
f.setAccessible(true);
f.set(null, null);
f = sun.jvm.hotspot.runtime.Threads.class.getDeclaredField("virtualConstructor");
f.setAccessible(true);
f.set(null, null);
f = sun.jvm.hotspot.runtime.Threads.class.getDeclaredField("access");
f.setAccessible(true);
f.set(null, null);

//reinit observer list
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
try {
Method initm = Threads.class.getDeclaredMethod("initialize", new Class<?>[] { TypeDataBase.class });
initm.invoke(null, new Object[] { VM.getVM().getTypeDataBase() });
}
catch (Exception e) {
e.printStackTrace();
}
}
});

但这会导致:

java.lang.RuntimeException: Unable to deduce type of thread from address 0xa5d12400 (expected type JavaThread, CompilerThread, ServiceThread, JvmtiAgentThread, or SurrogateLockerThread)
at sun.jvm.hotspot.runtime.Threads.createJavaThreadWrapper(Threads.java:152)
at sun.jvm.hotspot.runtime.Threads.first(Threads.java:140)
at sun.jvm.hotspot.runtime.DeadlockDetector.createThreadTable(DeadlockDetector.java:149)
at sun.jvm.hotspot.runtime.DeadlockDetector.print(DeadlockDetector.java:56)
at sun.jvm.hotspot.runtime.DeadlockDetector.print(DeadlockDetector.java:39)
at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:52)
at de.chili.savelogfiles.ChiliJStack.run(ChiliJStack.java:40)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at de.chili.savelogfiles.JStackFRunnable.run(JStackFRunnable.java:81)
at java.lang.Thread.run(Thread.java:722)
Caused by: sun.jvm.hotspot.types.WrongTypeException: No suitable match for type of address 0xa5d12400 (nearest symbol is _ZTV10JavaThread)
at sun.jvm.hotspot.runtime.InstanceConstructor.newWrongTypeException(InstanceConstructor.java:62)
at sun.jvm.hotspot.runtime.VirtualConstructor.instantiateWrapperFor(VirtualConstructor.java:80)
at sun.jvm.hotspot.runtime.Threads.createJavaThreadWrapper(Threads.java:148)
... 13 more
sun.jvm.hotspot.utilities.AssertionFailure: Expecting GenCollectedHeap, G1CollectedHeap, or ParallelScavengeHeap, but got sun.jvm.hotspot.gc_interface.CollectedHeap

我没有想法....

最佳答案

我在这里发现了一些有用的东西 http://crunchify.com/how-to-generate-java-thread-dump-programmatically

可能这会有所帮助,不知道 PID 和线程 ID 是否相同。

 final ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
final ThreadInfo[] threadInfos = threadMXBean.getThreadInfo(<thread Ids>, 100);

关于Java 以编程方式强制线程转储 - 如 "jstack -F -l <PID>",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28744850/

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