api-String Pool(字符串常量池)

I、缓存

String在JVM 内部使用 HashTable 进行缓存,且不可动态扩容。
api-String Pool(字符串常量池)_第1张图片

II、创建和回收

String#intern() 方法的作用是:
1、如果字符串未在 Pool 中,那么就往 Pool 中增加一条记录,然后返回 Pool 中的引用。
2、如果已经在 Pool 中,直接返回 Pool 中的引用。
只要 String Pool 中的 String 对象对于 GC Roots 来说不可达,那么它们就是可以被回收的。如果 Pool 中对象过多,可能导致 YGC 变长,因为 YGC 的时候,需要扫描 String Pool。

III、String Pool在 JVM 哪里

1、在 Java 6 中,String Pool 位于 PermGen Space 中,PermGen 是一个固定大小的区域,因此在 Java 6 中必须小心使用 String.intern() ,否则容易导致 OutOfMemoryError。
2、在 Java 7 中,String Pool 移到了堆中。调优工作需要调整堆大小。
3、在 Java 8 中,String Pool 依然还是在 Heap Space 中。

IV、容量

在 Java 6 中,HashTable 默认的 bucket 数量是 1009,可通过(-XX:StringTableSize=N配置)。到 Java 7和 Java 8里,默认值是 60013。
为什么是 1009,而不是 1000 或者 1024?因为 1009 是质数,有利于达到更好的散列。60013 同理。

V、JVM参数

两个 JVM 参数可以设置StringTableSize:
-XX:StringTableSize=N
-XX:+PrintStringTableStatistics

你可能感兴趣的:(java)