Java虚拟机——Java内存区域⽅法区

1:是什么

  • 是各个线程共享的内存区域,它⽤于存储已被虚拟机加载的类信息、常量、静态变量、即时 编译器编译后的代码等数据
  • 什么是类信息:类版本号、⽅法、接⼝
  1. 方法区(Method Area)存储的类信息

        对每个加载的类型(类class、接口interface、枚举enum、注解annotation),JVM必须在方法区中存储以下类型信息:

       这个类型的完整有效名称(全名=包名.类名)

       这个类型直接父类的完整有效名称( java.lang.Object除外,其他类型若没有声明父类,默认父类是Object)

       这个类型的修饰符(public、abstract、final的某个子集)

       这个类型直接接口的一个有序列表 
       除此之外还方法区(Method Area)存储类信息还有

           类型的常量池( constant pool),域(Field)信息,方法(Method)信息,除了常量外的所有静态(static)变量

      2 方法区(Method Area)存储的常量

              static final修饰的成员变量都存储于 方法区(Method Area)中
           2.1方法区(Method Area)存储的静态变量
              静态变量又称为类变量,类中被static修饰的成员变量都是静态变量(类变量)

             静态变量之所以又称为类变量,是因为静态变量和类关联在一起,随着类的加载而存在于方法区(而不是堆中)

             八种基本数据类型(byte、short、int、long、float、double、char、boolean)的静态变量会在方法区开辟空间,并将对应的值存储在方法方法区,对于引用类型的静态变量如果未用new关键字为引用类型的静态变量分配对象(如:static Object obj;)那么对象的引用obj会存储在方法区中,并为其指定默认值null;若,对于引用类型的静态变量如果用new关键字为引用类型的静态变量分配对象(如:static Person person = new Person();),那么对象的引用person 会存储在方法区中,并且该对象在堆中的地址也会存储在方法区中(注意此时静态变量只存储了对象的堆地址,而对象本身仍在堆内存中);这个过程还涉及到静态变量初始化问题

      3  方法区(Method Area)存储的方法(Method)
程序运行时会加载类编译生成的字节码,这个过程中静态变量(类变量)和静态方法及普通方法对应的字节码加载到方法区。但是!!!方法区中没有实例变量,这是因为,类加载先于对应类对象的产生,而实例变量是和对象关联在一起的,对象存放在堆里面,所以方法区中没有实例变量

静态变量(类变量)和静态方法及普通方法在方法区(Method Area)存储方式是有区别的
此部分内容参考:https://blog.csdn.net/u013241673/article/details/78574770

2:为什么? 

  • 内存中存放类信息、静态变量等数据,属于线程共享的⼀块区域
  • Hotspot使⽤永久代来实现⽅法区 JRockitIBM J9VM Java堆⼀样管理这部分内存

 3:特点?

 

  • 在JDK1.6及之前,运行时常量池是方法区的一个部分,同时方法区里面存储了类的元数据信息、静态变量、即时编译器编译后的代码(比如spring 使用IOC或者AOP创建bean时,或者使用cglib,反射的形式动态生成class信息等)等。
  • 在JDK1.7及以后,JVM已经将运行时常量池从方法区中移了出来,在JVM堆开辟了一块区域存放常量池。并⾮数据进⼊了⽅法区就如永久代的名字⼀样永久存在了。这区域的内存回收⽬标主要是针对常量池的回收和对类型的卸载
  • ⽅法区也会抛出OutofMemoryError,当它⽆法满⾜内存分配需求时

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章