JavaString存储原理


阳光少年     2020-08-19     1515

JavaString存储原理

目录

原文链接

总结: 基本类型的变量数据和对象的引用都是放在里面的,对象本身放在堆里面显式的String常量放在常量池,String对象放在堆中。

  • 常量池的说明

    • 常量池之前是放在方法区里面的,也就是在永久代里面的,从JDK7开始移到了堆里面。这一改变我们可以从oracle的release version的notes里的** Important RFEs Addressed in JDK 7 **看到。
    Area: HotSpot
    Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
    RFE: 6962931
  • String内存位置说明

    • 显式的String常量

String str1 = "123";
String str2 = "123";
  • 第一句代码执行后就在常量池中创建了一个值为123的String对象;
  • 第二句执行时,因为常量池中存在123所以就不再创建新的String对象了。
  • 此时该字符串的引用在虚拟机栈里面。
    • String对象

String str3 = new String("321");
String str4 = new String("321");
  • Class被加载时就在常量池中创建了一个值为321的String对象,第一句执行时会在堆里创建new String("321")对象;
  • 第二句执行时,因为常量池中存在321所以就不再创建新的String对象了,直接在堆里创建new String("321")对象。

验证

	public static void main(String[] args) {
		
		String str1 = "123";
		String str2 = "123";
		System.out.println(str1==str2);	//true
		
		String str3 = new String("321");
		String str4 = new String("321");
		System.out.println(str3==str4);	//false
	}
  • 面试题:以下代码,创建了几个对象

    • 答: 3个,字符串常量池中1个hello对象,堆内存中2个String对象
String str3 = new String("321");
String str4 = new String("321");

String存储内存结构图