5. JVM 的方法区

发布于:2025-07-15 ⋅ 阅读:(15) ⋅ 点赞:(0)

1. JVM介绍和运行流程-CSDN博客

2. 什么是程序计数器-CSDN博客

3. java 堆和 JVM 内存结构-CSDN博客

4. 虚拟机栈-CSDN博客

5. JVM 的方法区-CSDN博客

6. JVM直接内存-CSDN博客

7. JVM类加载器与双亲委派模型-CSDN博客

8. JVM类装载的执行过程-CSDN博客

9. JVM垃圾回收-CSDN博客

10. 垃圾回收的算法-CSDN博客

11. JVM中的分代回收-CSDN博客

12. JVM的垃圾回收器-CSDN博客

13. G1垃圾回收器-CSDN博客

14. 垃圾回收的引用区别-CSDN博客

15. JVM调优的参数设置-CSDN博客

16. JVM调优工具-CSDN博客


1. 什么是方法区

方法区是Java虚拟机(JVM)内存结构中的一个重要组成部分,主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

主要特点

  1. 共享内存区域:所有线程共享方法区

  2. 逻辑部分:是Java堆的逻辑组成部分

  3. 规范描述:在JVM规范中属于堆的一个逻辑部分,但习惯上被称为"非堆"(Non-Heap)

 发展与演进

  • 永久代(PermGen):在JDK7及之前,虚拟机用永久代来实现方法区。

  • 元空间(Metaspace)(方法区):从JDK8开始,永久代被移除,改用本地内存实现的元空间(方法区)。

存储内容 

方法区主要存储:

  • 类信息(Class元数据)

  • 运行时常量池

  • 静态变量

  • 即时编译器编译后的代码(JIT编译的本地代码)

  • 方法代码


2.  元空间的常量池

常量池(Constant Pool)是 Java 类文件(.class 文件)和 JVM 运行时内存中的一个重要数据结构,用于存储类、方法、字段等相关的符号引用和字面量。

它分为两种:

  1. Class 文件常量池(静态常量池,编译期生成)

  2. 运行时常量池(Runtime Constant Pool,JVM 运行时使用)

常量池 可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息 。 

可以使用下面的指令查看字节码结构(类的基本信息、常量池、方法定义):

javap -vApplication.class

例如下图: 


Class 文件常量池(静态常量池)

在 .class 文件中,常量池存储了类、方法、字段等的符号引用字面量,主要包括:

  • 字面量(Literals)

    • 字符串(如 "Hello"

    • 整数、浮点数(如 1003.14

    • 布尔值(true/false

    • null

  • 符号引用(Symbolic References)

    • 类和接口的全限定名(如 java/lang/Object

    • 字段的名称和描述符(如 name:Ljava/lang/String;

    • 方法的名称和描述符(如 main:([Ljava/lang/String;)V

特点

  • 编译期生成,存储在 .class 文件中

  • 不占用 JVM 内存,仅用于类加载时的解析


运行时常量池(Runtime Constant Pool)

当 JVM 加载类时,会将 Class 文件常量池的内容解析并存储到 方法区(元空间) 中的运行时常量池。它包含:

  • 解析后的直接引用(如方法、字段的内存地址)

  • 动态生成的常量(如 String.intern() 的字符串)

  • JVM 运行时的符号引用解析结果

特点

  • 存储在 方法区(JDK 8 后是元空间)

  • 可以动态添加(如 String.intern()

  • 如果内存不足,会抛出 OutOfMemoryError


3. 总结 

3.1 什么是方法区?

  • 方法区(Method Area)是各个线程共享的内存区域
  • 主要存储类的信息、运行时常量池
  • 虚拟机启动的时候创建,关闭虚拟机时释放
  • 如果方法区域中的内存无法满足分配请求,则会抛出OutOfMemoryError:Metaspace

3.2 介绍一下运行时常量池

  • 常量池:可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名方法名、参数类型、字面量等信息
  • 当类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址


网站公告

今日签到

点亮在社区的每一天
去签到