JVM--08 JVM方法区

摘抄自小涛涛~~~:小涛涛JVM系列博客

1、JAVA虚拟机方法区

        JAVA虚拟机方法区在JAVA虚拟机内存模型中位置如下图所示。

        方法区和堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、和编译器编译后的代

码(也就是存储字节码文件。.class)等数据,这里可以看到常量也会在方法区中,是因为方法区中有一个运行时常量池,为什么叫

运行时常量池,因为在编译后期生成的是各种字面量(字面量的意思就是值,比如int i=3,这个3就是字面量的意思)和符号引用,

这些是存放在一个叫做常量池(这个常量池是在字节码文件中)的地方,当类加载进入方法区时,就会把该常量池中的内容放入运

行时常量池中。

        这里要注意,运行时常量池和常量池,不要搞混淆了,字节码文件中也有常量池,在后面的章节会详细讲解这个东西。现在

只需要知道方法区中有一个运行时常量池,就是用来存放常量的。还有一点,运行时常量池不一定就一定要从字节码常量池中拿

取常量,可能在程序运行期间将新的常量放入池中,比如String.intern()方法,这个方法的作用就是:先从方法区的运行时常量

池中查找看是否有该值,如果有,则返回该值的引用,如果没有,那么就会将该值加入运行时常量池中。 

        运行时常量池Demo:

        执行下方代码,得到的结果代码中注释已有


   
   
  1. public class test {
  2. public static void main(String[] args) {
  3. String a = “aaa” ;
  4. String b = “aaa” ;
  5. System.out.println(a == b);
  6. //1、输出为true
  7. String c = new String(a);
  8. System.out.println(a == c);
  9. //2、输出为false
  10. System.out.println(a == c.intern());
  11. //3、输出为true
  12. }
  13. }
        第一次输出:

        在创建String a和b时,虚拟机会在运行时常量池中寻找”aaa”的串,如果存在,直接返回地址,如果不存在,创建后返回地址。这也就解释了为什么第一次输出位true的问题。

        第二次输出:

        当我们使用new String()创建c时候,c会被虚拟机创建在堆中,这就是为什么第二次输出为false。

        第三次输出:

        c.intern()方法是将c的值放入运行时常量池并返回地址,所以第三次比较结果为true;

猜你喜欢

转载自blog.csdn.net/PORSCHE_GT3RS/article/details/82635053
今日推荐