Java的字符串为什么挪到了堆里?

我们知道的2个事实:

1 字符串的值是放在常量池里的

2 hotspot vm在jdk1.7之前,常量池是放在方法区(堆外的永久代)

 

java在jdk1.7开始, 字符串挪到了堆里, 这么做的目的是什么?

1 堆内回收效率高: 堆外的方法区的内存(Class)回收效率(可回收比例和执行时间成本)不如堆内

2 永久代/元数据区一般不会设置一个很大的值.

永久代/元数据区由于(字符串/动态加载jar/cglib生成的类(rpc orm)/lambda/反应式编程),容易导致OOM

一般堆内存会被设置为一个比较大的值,在常量池(含字符串)占用很大的情况下,不容易导致OOM

3 String.intern()方法的效率提升, 节省了复制堆中的字符串到常量池中的成本.

如果调用 intern 方法,会去查看字符串常量池中是否有等于该对象的字符串的引用,如果没有,在 JDK1.6 版本中会复制堆中的字符串到常量池中,并返回该字符串引用,堆内存中原有的字符串由于没有引用指向它,将会通过垃圾回收器回收。

在 JDK1.7 版本以后,由于常量池已经合并到了堆中,所以不会再复制具体字符串了

 

总结是两个原因:

  1. 避免OOM
  2. 提高执行效率

你可能感兴趣的:(JVM,JVM,Java字符串)