由intern方法聊聊虚拟机内存划分


上图是在jdk1.6里的运行结果
这是在jdk8中的运行结果
上图是在jdk8中的运行结果

先说原因:1.6中,intern()方法会把首次遇到的字符串实例复制到永久代的字符串常量池 中存储,返回的也是永久代里面这个字符串实例的引用,而由StringBuilder创建的字符串对象实例在 Java堆上,所以必然不可能是同一个引用,结果将返回false。1.6中还有永久代(就是方法区)这个东西,但是到了8没有了。原来的方法区会存放类的信息(如类名、类的版本、访问修饰符、字段描述、方法描述等)、常量池、静态变量等,常量池就包含字符串常量池,到了8没了这个方法区,常量池到了堆heap中,那只需要在常量池里记录一下首次出现的实例引 用即可,因此intern()返回的引用和由StringBuilder创建的那个字符串实例就是同一个。注意图2里12行和13行打印的结果不同是因为s1和s2本来就是两个不同的对象,abc第一次出现在s1上。

jdk1.7之前:方法区位于永久代(PermGen),永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变;
jdk.7:存储在永久代的部分数据就已经转移到Java Heap或者Native memory。但永久代仍存在于JDK 1.7中,并没有完全移除,譬如符号引用(Symbols)转移到了native memory;字符串常量池(interned strings)转移到了Java heap;类的静态变量(class statics variables )转移到了Java heap;
jdk1.8:仍然保留方法区的概念,只不过实现方式不同。取消永久代,方法存放于元空间(Metaspace),元空间仍然与堆不相连,但与堆共享物理内存,逻辑上可认为在堆中。

1)移除了永久代(PermGen),替换为元空间(Metaspace);
2)永久代中的 class metadata 转移到了 native memory(本地内存,而不是虚拟机);
3)永久代中的 interned Strings 和 class static variables 转移到了 Java heap;
4)永久代参数 (PermSize MaxPermSize) -> 元空间参数(MetaspaceSize MaxMetaspaceSize)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值