是否有任何实用程序或脚本(使用Java或本机代码)来查看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进程。
一些更多 的可维护性代理 的例子在这里。
更新
如果您希望扫描所有字符串,而不仅仅是字符串池中的字符串,则可以使用类似的方法。只需替换getStringTable().stringsDo()
为getObjectHeap().iterateObjectsOfKlass()
。实例。
更新2
也可以使用JVMTI函数IterateThroughHeap从Java进程中遍历Java
Heap 。这将不会比Serviceability Agent更具干扰性。
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);
}
完整的示例在这里。
本文向大家介绍Java程序访问字符串字符,包括了Java程序访问字符串字符的使用技巧和注意事项,需要的朋友参考一下 要在Java中访问字符串的字符,请使用方法。该位置将作为参数添加。 假设我们有以下字符串- 让我们使用method在第4个位置找到字符。 以下是最后一个示例。 示例 输出结果
每个人都知道这一点。Net framework字符串对象直接存储在堆内存中 我只是想弄清楚里面是否有保留的记忆。Net字符串框架。在java中,有一个为字符串保留的内存,称为SCMP(字符串常量内存池),在这里字符串被初始化和垃圾收集,就像堆内存中的其他对象一样。
问题内容: 我要执行以下操作。 我想要所有超链接的行为进行ajax调用并检索html。 不幸的是,您不能简单地用ajax响应中收到的html替换当前的html。 如何仅获取ajax响应的标记中的内容,以便 仅 替换现有html中正文的内容。 编辑:开始标记并不总是这样,有时可能会有一个类,例如 问题答案: 如果我对您的理解正确,请使用正则表达式在body标签之间获取内容。 编辑 根据您在下面的评论
当使用文字创建字符串时,它会存储在池中。但当使用new运算符创建字符串对象时,它会将对象存储在堆中。 但是,堆中的对象只是一个指向存储在池中的文本的指针,还是一个存储在堆中的简单字符串对象,符合GC的条件?
我一直在尝试从一个有一万亿个字符的字符串中访问一个字符。我使用BigInteger从字符串中获取索引号,并使用charAt方法从字符串中访问字符。 我试图做的是计算给定字符串中特定字符的出现次数。 例如,字符串:
问题内容: 考虑以下代码: 使用new关键字时,Java会 再次创建吗?这将存储在常规堆还是池中?多少人在将s结尾池? 问题答案: 如果使用关键字,将创建一个新对象。请注意,对象始终在堆上-字符串池不是与堆分开的独立内存区域。 字符串池就像一个缓存。如果你这样做: 那么Java编译器是聪明足以让只有一个对象,并且将两者指的是同一个String对象。如果你这样做: 那么池中将有一个对象,该对象代表文