JVM(HotSpot):字符串常量池(StringTable)

文章目录

一、内存结构图

JDK1.6

JDK1.8

我们发现,StringTable移入了Heap里面。所以,应该想到,StringTable将受到GC管理。

其实,1.6中,在方法区中的时候,也是受GC管理的。

二、案例讲解

题目

java 复制代码
public class Demo7 {
	public static void main(String[] args) {
		String s1 = "a";
		String s2 = "b";
		String s3="a" + "b";
		String s4 = s1 + s2;
		String s5 = "ab";
		String s6 = s4.intern();

		//问提
		System.out.println(s3 == s4);
		System.out.println(s3 == s5);
		System.out.println(s3 == s6);

		String x2 = new String("c") + new String("d");
		String x1 = "cd";
		x2.intern();

		//问,如果调换了最后两行代码,如果是1.6,?
		System.out.println(x1 == x2);
	}
}

首先,我们要知道,== 号进行的比较,是比较引用的内存地址是否相同。

如果想要比较String的内容,用equals方法就可以。

字节码

主要看下红线处的几行代码

简单理解就是:

1、StringTable是一个HashTable结构(桶(数组)+链表

2、代码翻译

java 复制代码
String s1 = "a";
String s2 = "b";
String s3="a" + "b";
String s4 = s1 + s2;

前三行代码可以简单的理解为,JVM启动后,会创建一个StringTable

我现在简单点把StringTable表示成StringTable[]这样

于是

上面三行代码就是
StringTable [ "a", "b" ,"ab" ]

最后一行代码是
new StringBuilder().append("a").append("b").toString() new String("ab")

intern方法

就是将字符串主动放入StringTable中,并返回StringTable中的引用地址。

1.8和1.6的区别就是

1.8不在复制对象。所以,原来的引用指向会发生改变。

而1.6是复制对象,所以,原来的引用指向不会发生变化。

三、总结

常量池中的字符串仅仅是一个符号,第一次用到时,才会变成对象。

利用串池的机制,来避免重复创建字符串对象。

字符串变量凭借的原理是StringBuilder(1.8)

字符串常量凭借的原理是编译期优化

可以用intern方法,主动将串池中没有的字符串对象放入串池中。

  • 1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串
    池中的对象引用返回
  • 1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,
    放入串池, 会把串池中的对象引用返回

简单记忆

字符串的创建方式,如果是new的方式,就是放入堆中,而不放入串池中。

如果是""双引号方式创建,则是直接放入串池中。

相关推荐
吴冰_hogan6 小时前
JVM(Java虚拟机)的组成部分详解
java·开发语言·jvm
东阳马生架构13 小时前
JVM实战—1.Java代码的运行原理
jvm
ThisIsClark16 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
王佑辉16 小时前
【jvm】内存泄漏与内存溢出的区别
jvm
大G哥19 小时前
深入理解.NET内存回收机制
jvm·.net
泰勒今天不想展开19 小时前
jvm接入prometheus监控
jvm·windows·prometheus
东阳马生架构2 天前
JVM简介—3.JVM的执行子系统
jvm
程序员志哥2 天前
JVM系列(十三) -常用调优工具介绍
jvm
后台技术汇2 天前
JavaAgent技术应用和原理:JVM持久化监控
jvm