记录一下(并不知道到底对不对的,我觉得应该没什么问题):
首先是类的池常量,这部分是在方法区中的,而在jdk1.8以后,永久代已经被移除了,所以现在这部分应该在元空间中了,就是在本地内存中。
运行时常量池,这个是方法区的一部分,所以也是在元空间中。
字符串常量池,这个在jdk1.7以后就已经被移出方法区了,移动到堆中了,所以这个是在堆中,但是应该是在堆中独立的一部分。
注意:永久代被认为是方法区的实现,而方法区又是逻辑上堆的一部分,但是,又被称为非堆。。。。在jdk1.8,直接把这个干掉了,加了一个元空间。
这里还有一个intern方法的解释:
String str1=new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern()==str1);
String str2=new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);
第一个返回是true,第二个是false,对于jdk1.6什么的就不谈了,太远了,这里想说的是str1 是stringbuilder里的,是new出来的,是堆上的。所以intern以后,
会在字符串常量池中加一个引用指向这个“计算机软件”,而第二个这个java是个关键字,所以字符串常量池中已经有这个java了,所以intern的是指向常量池中的那个
“java”,而str2指向的是那个堆上的“Java”,所以这两个返回false,指向的不是同一块地址空间。