【jvm】方法区的理解
目录
-
-
-
-
- [1. 说明](#1. 说明)
- [2. 方法区的演进](#2. 方法区的演进)
- [3. 内部结构](#3. 内部结构)
- [4. 作用](#4. 作用)
- 5.内存管理
1. 说明
- 1.方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等数据。它是各个线程共享的内存区域。
- 2.尽管《Java虚拟机规范》中把方法区描述为堆的一个逻辑部分,但它却有一个别名叫作"非堆"(Non-Heap),目的是与Java堆区分开来。
- 3.与Java堆一样,方法区是各个线程共享的内存区域。
- 4.JVM方法区是Java虚拟机内存结构中的一个重要组成部分,它用于存储类的元数据、常量池、方法信息和静态变量等。
- 5.随着JDK版本的演进,方法区的实现方式也在不断变化,但其在Java虚拟机中的作用和地位始终不变。
2. 方法区的演进
- 1.永久代(PermGen):在JDK 1.7及以前,HotSpot JVM使用永久代来实现方法区。这种方式下,方法区的内存管理类似于Java堆,但存在内存溢出的风险,因为永久代有上限(通过参数-XX:MaxPermSize设置,即使不设置也会有默认大小)。
- 2.元空间(MetaSpace):从JDK 8开始,HotSpot JVM改用元空间来实现方法区。元空间使用本地内存(Native Memory),由操作系统直接管理,因此其空间上限与操作系统相关。当大量加载类时,不用担心方法区溢出。元空间的使用可以通过参数-XX:MetaSpaceSize和-XX:MaxMetaSpaceSize来调整其初始大小和最大容量。
3. 内部结构
- 1.类型信息:存储每个加载的类(Class)、接口(interface)、枚举(enum)、注解(annotation)的类型信息,包括类型的完整有效名称、直接父类的完整有效名称、直接接口的序列集以及类型的修饰符。
- 2.域信息:存储类的所有域信息,包括域名称、域类型、域修饰符。
- 3.方法信息:存储方法的相关信息,包括方法名、方法返回类型、方法的参数的数量和类型、方法的字节码、方法的修饰符以及方法的异常表。
- 4.运行时常量池:方法区的一部分,用于存储编译期生成的各种字面量和符号引用,包括字符串、数字、类和方法的符号引用等。在类加载后,字节码文件中的常量池会被加载到运行时常量池中,供运行时使用。
4. 作用
- 1.方法区在Java虚拟机内存中扮演了类的元数据存储和管理的角色。
- 2.它不仅保存了类的结构信息,还包括了支持类运行时行为的相关数据。
- 3.方法区的设计使得虚拟机能够高效地加载、存储和管理类信息,保证类的正确性和一致性。
5.内存管理
- 1.内存分配:方法区的内存大小通常由JVM的启动参数控制。在JDK 8及以后,由于元空间使用本地内存,因此其内存分配更加灵活。
- 2.垃圾回收:方法区也会进行垃圾回收,主要回收不再存活的类信息。当方法区无法满足内存分配请求时,会抛出OutOfMemoryError异常。