首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >访问JDK 8 HotSpot JVM中字符串池内容的实用程序

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

Stack Overflow用户
提问于 2016-02-06 08:17:28
回答 1查看 975关注 0票数 6

是否有任何实用程序或脚本使用java或本机代码来查看JDK8JVM中字符串池中所有字符串的列表,而不会对HotSpot产生很大的性能影响?

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

谢谢你,哈里什

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-06 12:45:40

您可以使用默认情况下包含在JDK中的HotSpot服务性代理轻松地自己编写实用程序。

代码语言:javascript
复制
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进程。

再举几个适用性Agent的例子,here

更新

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

更新2

还可以使用JVMTI函数IterateThroughHeap从Java进程中迭代Java。这将不会像服务性代理那样具有侵扰性。

代码语言:javascript
复制
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

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35238902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档