[英]HotSpot Serviceability Agent's iterateObjectsOfKlass() is too slow
[英]Java Hotspot Serviceability Agent SystemDictionary.ClassVisitor unavailable since JDK11
我正在嘗試構建一個非常基本的 Java 熱點可維護性代理來轉儲一個特定加載方法的字節碼。 這是我代理的代碼:
package sun.jvm.hotspot.jdi;
import sun.jvm.hotspot.oops.InstanceKlass;
import sun.jvm.hotspot.oops.Method;
import sun.jvm.hotspot.oops.Klass;
import sun.jvm.hotspot.memory.SystemDictionary;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;
public class GetBytecode extends Tool {
@Override
public void run() {
VM.getVM().getSystemDictionary().allClassesDo(new SystemDictionary.ClassVisitor() {
public void visit(Klass klass) {
if (klass.getName().asString().equals("MyDebugger")) {
Method method = ((InstanceKlass) klass).findMethod("sendMessage", "()V");
for (byte bc : method.getByteCode()) {
System.out.printf("%02x ", bc);
}
}
}
});
}
public static void main(String[] args) {
new GetBytecode().execute(args);
}
}
我用以下行編譯:
javac --add-modules=jdk.hotspot.agent --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.memory.SystemDictionary=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.memory=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.oops=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.tools=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.runtime=ALL-UNNAMED" --add-exports "jdk.hotspot.agent/sun.jvm.hotspot.classfile=ALL-UNNAMED" *.java
它修復了我之前遇到的導入問題,但似乎自 JDK11 以來, SystemVisitor.ClassVisitor
接口不再存在,因為我在編譯時遇到錯誤:
GetBytecode.java:14: error: cannot find symbol
VM.getVM().getSystemDictionary().allClassesDo(new SystemDictionary.ClassVisitor() {
^
symbol: class ClassVisitor
location: class SystemDictionary
1 error
另外,我在網上找不到任何文檔,這太令人沮喪了...... 請參閱 javadoc
歡迎任何修復/解決方法:)
jdk.hotspot.agent
是一個 JDK 內部模塊,不是任何標准的一部分,不適合最終用戶,因此沒有記錄。
因此,這個模塊的 API 即使在 JDK 的次要更新中也可以任意更改。 為一個版本的 JDK 編寫的代碼不需要與其他 JDK 版本兼容。 這是很容易理解的,因為 Serviceability Agent 反映了內部 JVM 結構,這些結構可能會在不同版本之間發生變化(並且確實會發生變化)。
所以你需要一個不同的 JDK 11 代碼。它可能看起來像這樣:
import sun.jvm.hotspot.oops.InstanceKlass;
import sun.jvm.hotspot.oops.Method;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;
public class GetBytecode extends Tool {
@Override
public void run() {
VM.getVM().getSystemDictionary().sharedDictionary().allEntriesDo((klass, loader) -> {
if (klass.getName().asString().equals("MyDebugger")) {
Method method = ((InstanceKlass) klass).findMethod("sendMessage", "()V");
for (byte bc : method.getByteCode()) {
System.out.printf("%02x ", bc);
}
}
}, null);
}
public static void main(String[] args) {
new GetBytecode().execute(args);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.