JAVA基础篇005-方法区是什么、方法区存放什么

目录

一、方法区定义(Method Area)

二、方法区特点

三、方法区存放的内容

1.类型信息

2.类型的常量池( constant pool)

3.域信息

4.方法信息

5.类变量

6.对类加载器的引用

7.对Class类的引用

8.方法表


一、方法区定义(Method Area)

《深入理解JVM》书中描述如下:

方法区(Method Area)与Java堆一样,是各个线程共享的内存区域。

二、方法区特点

1.方法区是线程共享的,多个线程都用到一个类的时候,若这个类还未被加载,应该只有一个线程去加载类,其他线程等待;

2.方法区的大小可以是非固定的,jvm可以根据应用需要动态调整,jvm也支持用户和程序指定方法区的初始大小;

3.方法区有垃圾回收机制,一些类不再被使用则变为垃圾,需要进行垃圾清理。

三、方法区存放的内容

《深入理解JVM》书中描述如下:

它存储已被Java虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。

本文对存放内容画了粗图以便大家理解记忆,如下:

1.类型信息

对每个加载的类型,jvm必须在方法区中存储以下类型信息:
1.类型的完整有效名;
2.直接父类的完整有效名(除非当前类型是Interface 或 java.lang.Object,两者都没有父类);
3.类型的修饰符(public,abstract, final等);

总结来说就是一个类上户口,需要知道这个类的名字叫什么、父亲是谁、有没有实现接口、 权限是什么。

2.类型的常量池( constant pool)

已加载的类型(每一个class文件中),都维护着一个常量池(不同于方法区的运行时常量池),里面存放着编译时期生成的各种字面值(像string、基本数据类型、以及它们的包装类的值、及final修饰的变量,即在编译期间就确定下来的值)和符号引用(对类型、域、方法的引用);这个常量池的内容在类加载的时候,被复制到方法区的运行时常量池;池中的数据项类似数组项一样,是通过索引访问的。

3.域信息

类型的所有域的相关信息(域名、域类型、域修饰符如<public、private、protected>等),以及域的声明顺序;

4.方法信息

声明的顺序、修饰符、返回值类型、名字、参数列表(有序保存)、异常表(方法抛出的异常)、方法字节码(native、abstract方法除外)、操作数栈和局部变量表大小

5.类变量

jvm使用一个类之前,必须在方法区中为每个非final类变量分配空间,非final类变量存储在定义它的类中;

PS:final类变量不存储在这里,由于final的不可改变性,final类变量的值在编译期间就被确定了,因此保存在类的常量池里面,然后在加载类的时候,复制进方法区的运行时常量池里面,final类变量存储在运行时常量池里面,每一个使用它的类保存着一个对其的引用。

6.对类加载器的引用

jvm必须知道一个类型是由启动加载器加载的还是由用户类加载器加载的,如果一个类型是由用户类加载器加载的,那么jvm会将这个类加载器的一个引用作为类型信息的一部分保存在方法区中。jvm在动态链接的时候需要这个信息,当解析一个类型到另一个类型的引用的时候,jvm需要保证这两个类型的类加载器是相同的,这对jvm区分名字空间的方式是至关重要的。

7.对Class类的引用

jvm为每个加载的类都创建一个java.lang.Class的实例(存储在堆上),而jvm必须以某种方式把Class的这个实例和存储在方法区中的类型数据(类的元数据)联系起来。

8.方法表

java语言始终是把安全放在首位,难免牺牲效率为代价的,为了提高应用效率jvm还添加了法表,jvm可以通过方法表快速激活实例方法。

JAVA基础篇专栏持续更新中,更多JAVA基础知识请移步专栏垂阅,希望对您有帮助!

原创文章 15 获赞 20 访问量 7393

猜你喜欢

转载自blog.csdn.net/duoyu779553/article/details/105878755
今日推荐