以前每次学习JVM都有涉及到对方法区的学习,看网上一些文章或视频介绍对于方法区的描述五花八门,很多都说的模棱两可,对于方法区的理解很不准确,学习完不久后就忘记了。所以决定从权威的官方介绍来理解方法区到底是什么。
一、方法区定义
从JVM官方对方法区介绍原文来准确的理解方法区是什么!!!
英文原版链接:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.5.4
The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the “text” segment in an operating system process. It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.
Java虚拟机中有一个被所有jvm线程共享的方法区。方法区有点类似于传统编程语言中的编译代码块或者操作系统层面的代码段。它存储着每个类的构造信息,譬如运行时的常量池,字段,方法数据,以及方法和构造方法的代码,包括一些在类和实例初始化和接口初始化时候使用的特殊方法。
The method area is created on virtual machine start-up. Although the method area is logically part of the heap, simple implementations may choose not to either garbage collect or compact it. This specification does not mandate the location of the method area or the policies used to manage compiled code. The method area may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger method area becomes unnecessary. The memory for the method area does not need to be contiguous.
方法区在jvm启动时候被创建。虽然方法区在逻辑层面上是堆的一部分,但是就简单实现来说既不会被回收也不会被压缩。这个规范并不强制指定方法区存放的位置也不会对编译过的代码有管理策略的限制。方法区可能有一个固定的大小或者也可以通过计算大小去扩展也可以在不需要的时候被压缩。方法区的内存也不需要是连续的。
A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of the method area, as well as, in the case of a varying-size method area, control over the maximum and minimum method area size.
Jvm虚拟机实现可以提供给编程人员或者用户初始化方法区的大小,同时在方法区可变大小的情况下,控制这个方法区的最大值和最小值
The following exceptional condition is associated with the method area:
下面这种异常情况是和方法区有关联的:
-
If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an
OutOfMemoryError
.如果方法区满足不了构造所需要的内存,jvm就会抛出OutOfMemoryError。
二、自己对原文的理解总结
- 方法区是一个逻辑概念上的定义,并不是真正的实现。他的实现是由真正的JVM厂商来进行实现(类似于Java中的接口和接口实现类的关系)。
- 方法区是所有JVM共享的。
- 方法区一般用于存放常量池、类的Class信息、ClassLoader、字段、方法数据等。
- 逻辑上是属于堆的一部分,但是在各个JVM厂商实现的时候可以不放在JVM堆空间中(比如在JDK1.8以后,方法区的实现由永久代变为了元空间,并且放在了堆外内存,不受JVM垃圾收集器管理)。
- JDK1.8之前方法区的实现叫做永久代,JDK1.8之后方法区的实现叫做元空间。
三、JVM1.8之前和之后JVM内存结构的区别
①、在JVM1.8之前,内存结构
- 可以看到方法区的实现叫做永久代
- 方法区位于JVM内存结构之内(也可以理解为在是堆空间的一部分)
- stringTable位于运行时常量池中
②、在JVM1.8之后,内存结构
- 可以看到方法区的实现由永久代变为了元空间
- 方法区位于JVM内存结构之外(即方法区位于堆外内存中,也就是机器的物理内存中。不受JVM垃圾回收管理)
- stringTable的位置由常量池变动到了堆空间