gpt4 book ai didi

java - 用于访问 JDK 8 HotSpot JVM 中字符串池内容的实用程序

转载 作者:太空宇宙 更新时间:2023-11-04 10:27:02 24 4
gpt4 key购买 nike

是否有任何实用程序或脚本(使用 java 或 native 代码)可以查看 JDK 8 HotSpot JVM 中字符串池中存在的所有字符串的列表,而不会对 JVM 产生很大的性能影响?

或者,每当将新字符串添加到 JVM 中时,我是否可以连接一个监听器?

谢谢,哈里什

最佳答案

您可以使用默认包含在 JDK 中的 HotSpot Serviceability Agent 轻松地自己制作这样的实用程序。

import sun.jvm.hotspot.memory.SystemDictionary;
import sun.jvm.hotspot.oops.InstanceKlass;
import sun.jvm.hotspot.oops.OopField;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.tools.Tool;

public class InternedStrings extends Tool {

@Override
public void run() {
// Use Reflection-like API to reference String class and String.value field
SystemDictionary dict = VM.getVM().getSystemDictionary();
InstanceKlass stringKlass = (InstanceKlass) dict.find("java/lang/String", null, null);
OopField valueField = (OopField) stringKlass.findField("value", "[C");

// Counters
long[] stats = new long[2];

// Iterate through the String Pool printing out each String object
VM.getVM().getStringTable().stringsDo(s -> {
s.printValueOn(System.out);
System.out.println();
stats[0]++;
stats[1] += s.getObjectSize() + valueField.getValue(s).getObjectSize();
});

System.out.printf("%d strings with total size %d\n", stats[0], stats[1]);
}

public static void main(String[] args) {
// Use default SA tool launcher
new InternedStrings().execute(args);
}
}

运行该工具:
java -cp $JAVA_HOME/lib/sa-jdi.jar:. InternedStrings <PID>

警告:这是一个外部工具,会在执行时暂停目标 JVM 进程。

更多可服务性代理示例here .

更新

如果你想扫描所有字符串,而不仅仅是字符串池中的字符串,你可以使用类似的方法;只需替换 getStringTable().stringsDo()getObjectHeap().iterateObjectsOfKlass()Example .

更新2

还可以使用 JVMTI 函数从 Java 进程内迭代 Java 堆 IterateThroughHeap 。这比可服务性代理的侵入性要小。

jint JNICALL stringCallback(jlong class_tag, jlong size, jlong* tag_ptr,
const jchar* value, jint value_length, void* user_data) {
wprintf(L"%.*s\n", value_length, value);
return 0;
}

JNIEXPORT void JNICALL Java_HeapIterator_printStrings(JNIEnv* env, jclass cls) {
jvmtiHeapCallbacks callbacks = {NULL, NULL, NULL, NULL, stringCallback};
(*jvmti)->IterateThroughHeap(jvmti, 0, NULL, &callbacks, NULL);
}

完整的示例是 here .

关于java - 用于访问 JDK 8 HotSpot JVM 中字符串池内容的实用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50420392/

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