常量池、运行时常量池、字符串常量池
Java里包含各种常量池,经常傻傻分不清楚,下面就简单梳理下Java中的池们。
概念解释
常量池
这里的常量池指的是Class文件常量池。常量池里主要放两类常量:
- 字面量 :Java语言中定义的常量,如使用final修饰的值
- 符号引用 :表示JVM定义的Java关键字或基本类型与实际结构转换关系
符号引用主要包含以下三种类型:
类和接口的全限定名(Fully Qualified Name)
字段的名称和描述符(Descriptor)
方法的名称和描述符
上面说的常量池在JVM中的结构都是一张表。具体有哪些类型的表可以参考下图
运行时常量池
运行时常量池就是类被JVM加载后在JVM中的版本。有一点儿区别就是常量池只有类文件在编译的时候才会产生,而且是存储在类文件中的。而运行时常量池是在方法区,而且可在JVM运行期间动态向运行时常量池中写入数据。
字符串常量池
字符串常量池是因为Java为String开辟的一块内存缓冲区,为了提高性能同时减少内存开销。在JVM中,字符串常量池由一个hash表实现。默认容量为1009。当字符串常量池中的存储比较多的字符串时,会导致hash冲突,从而每个节点形成长长的链表,导致性能下降。所以在使用字符串常量池时,一定要控制容量。
-XX:StringTableSize
通过这个参数可以指定字符串常量池的容量
不同Jdk中字符串常量池的演化
jdk6及以前字符串常量池中存放的是字符串常量
jdk7字符串常量池中存放的是指定字符串的引用
参考
- <<深入理解Java虚拟机: JVM高级特性与最佳实践>>