关于JVM方法区和运行时常量池

方法区

  • 同 Java 堆一样,方法区也是全局共享的一块内存区域
  • 方法区的作用是存储 Java 类的结构信息,当我们创建对象实例后,对象的类型信息存储在方法堆之中,实例数据存放在堆中;实例数据指的是在 Java 中创建的各种实例对象以及它们的值,类型信息指的是定义在 Java 代码中的常量、静态变量、以及在类中声明的各种方法、方法字段等等;同时可能包括即时编译器编译后产生的代码数据。
  • JVMS 不要求该区域实现自动的内存管理,但是商用 JVM 一般都已实现该区域的自动内存管理。
  • 方法区分配内存可以不连续,可以动态扩展。
  • 该区域并非像 JMM 规范描述的那样数据一旦放进去就属于 “永久代”;在该区域进行内存回收的主要目的是对常量池的回收和对内存数据的卸载;一般来说这个区域的内存回收效率比起 Java 堆要低得多。
  • 当方法区无法满足内存需求时,将抛出 OutOfMemoryError 异常。

运行时常量池

  • 运行时常量池是方法区的一部分,所以也是全局共享的。
  • 其作用是存储 Java 类文件常量池中的符号信息。
  • class 文件中存在常量池(非运行时常量池),其在编译阶段就已经确定;JVM 规范对 class 文件结构有着严格的规范,必须符合此规范的 class 文件才会被 JVM 认可和装载。
  • 运行时常量池 中保存着一些 class文件中描述的符号引用,同时还会将这些符号引用所翻译出来的直接引用存储在 运行时常量池 中。
  • 运行时常量池相对于class常量池一大特征就是其具有动态性,Java 规范并不要求常量只能在运行时才产生,也就是说运行时常量池中的内容并不全部来自 class 常量池,class 常量池并非运行时常量池的唯一数据输入口;在运行时可以通过代码生成常量并将其放入运行时常量池中。
  • 同方法区一样,当运行时常量池无法申请到新的内存时,将抛出 OutOfMemoryError 异常。

猜你喜欢

转载自blog.csdn.net/qq_38337799/article/details/83119514