基于Java中字符串内存位置详解
前言
之前写过一篇关于JVM内存区域划分的文章,但是昨天接到蚂蚁金服的面试,问到JVM相关的内容,解释一下JVM的内存区域划分,这部分答得还不错,但是后来又问了Java里面String存放的位置,之前只记得String是一个不变的量,应该是要存放在常量池里面的,但是后来问到new一个String出来应该是放到哪里的,这个应该是放到堆里面的,后来又问到String的引用是放在什么地方的,当时傻逼的说也是放在堆里面的,现在总结一下:基本类型的变量数据和对象的引用都是放在栈里面的,对象本身放在堆里面,显式的String常量放在常量池,String对象放在堆中。
常量池的说明
常量池之前是放在方法区里面的,也就是在永久代里面的,从JDK7开始移到了堆里面。这一改变我们可以从oracle的releaseversion的notes里的**ImportantRFEsAddressedinJDK7**看到。
Area:HotSpot Synopsis:InJDK7,internedstringsarenolongerallocatedinthepermanentgenerationoftheJavaheap,butareinsteadallocatedinthemainpartoftheJavaheap(knownastheyoungandoldgenerations),alongwiththeotherobjectscreatedbytheapplication.ThischangewillresultinmoredataresidinginthemainJavaheap,andlessdatainthepermanentgeneration,andthusmayrequireheapsizestobeadjusted.Mostapplicationswillseeonlyrelativelysmalldifferencesinheapusageduetothischange,butlargerapplicationsthatloadmanyclassesormakeheavyuseoftheString.intern()methodwillseemoresignificantdifferences. RFE:6962931
String内存位置说明
1.显式的String常量
Stringa="holten"; Stringb="holten";
•第一句代码执行后就在常量池中创建了一个值为holten的String对象;
•第二句执行时,因为常量池中存在holten所以就不再创建新的String对象了。
•此时该字符串的引用在虚拟机栈里面。
1.String对象
Stringa=newString("holtenObj"); Stringb=newString("holtenObj");
•Class被加载时就在常量池中创建了一个值为holtenObj的String对象,第一句执行时会在堆里创建newString("holtenObj")对象;
•第二句执行时,因为常量池中存在holtenObj所以就不再创建新的String对象了,直接在堆里创建newString("holtenObj")对象。
验证一下
/** *Createdbyholten.gaoon2016/8/16. */ publicclassMain{ publicstaticvoidmain(String[]args){ Stringstr1="高小天"; Stringstr2="高小天"; System.out.println(str1==str2);//true Stringstr3=newString("高大天"); Stringstr4=newString("高大天"); System.out.println(str3==str4);//false } }
返回结果:
true false
以上这篇基于Java中字符串内存位置详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。