1:是什么
运⾏时常量池是⽅法区的⼀部分,Class⽂件除了有类的版本、字段、⽅法、接⼝等描述信息 外,还有⼀项信息是常量池,⽤于存放编译器⽣成的各种字⾯量和符号引⽤,这部分内容将 在类加载后进⼊⽅法区的运⾏时常量池中存放。
2:模拟常量池
程序运行的结果为 true,false,true,
第一个是true,原因是两个普通变量(不是通过new方式创建,所以不在堆中开辟空间给变量)把值存储到方法区的Stringtable里面,而StringTable的数据结构为HashSet,意思是不允许重复,当字符串c要存储值的时候发现方法区已经存在“abc”的值,无法存储,只能讲引用指向了方法区已存在的“abc”,所以第一个结果为true
第二个是false,因为通过new方式创建对象实例,堆中开辟空间给变量存储值,而a和c虽然值相同,但不在同一块内存区域里面,存储位置不一样,所以第二个判断为false
3:方法区与常量池的区别
在Java虚拟机规范中,方法区在虚拟机启动的时候创建,虽然方法区是堆的逻辑组成部分,但是简单的虚拟机实现可以选择不在方法区实现垃圾回收与压缩。这个版本的虚拟机规范也不限定实现方法区的内存位置和编译代码的管理策略。所以不同的JVM厂商,针对自己的JVM可能有不同的方法区实现方式。
在HotSpot中,设计者将方法区纳入GC分代收集。HotSpot虚拟机堆内存被分为新生代和老年代,对堆内存进行分代管理,所以HotSpot虚拟机使用者更愿意将方法区称为老年代。
方法区和永久代的关系很像Java中接口和类的关系,类实现了接口,而永久代就是HotSpot虚拟机对虚拟机规范中方法区的一种实现方式。
- 方法区是JVM规范概念,而永久代则是Hotspot虚拟机特有的概念
- 方法区和堆内存的永久代其实一个东西,一个是理论,一个是具体的实现