JVM(Java Virtual Machine)的知识体系可以大致分为以下几个方面:
-
JVM体系结构:
- 类加载子系统: 负责加载
.class文件到JVM中,并将这些内容转换成方法区中的运行时数据结构。 - 运行时数据区域: 包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区等。
- 执行引擎: 包含解释器、即时编译器(JIT Compiler)、垃圾回收器等。
- 类加载子系统: 负责加载
-
运行时数据区域:
- 程序计数器(Program Counter Register): 用于记录当前线程所执行的字节码指令的地址。
- Java虚拟机栈(Java Virtual Machine Stack): 每个线程私有,用于存储局部变量、操作数栈、动态链接、方法出口等信息。
- 本地方法栈(Native Method Stack): 用于存储Native方法调用的信息。
- Java堆(Java Heap): 所有线程共享,用于存储对象实例和数组。
- 方法区(Method Area): 存储已被虚拟机加载的类信息、常量、静态变量等数据。
- 运行时常量池(Runtime Constant Pool): 是方法区的一部分,用来存放编译期生成的各种字面量和符号引用。
-
类加载机制:
- 类如何被加载、连接和初始化的过程。
- 类加载器的种类及其层次结构(启动类加载器、扩展类加载器、应用类加载器等)。
- 双亲委派模型。
-
垃圾回收(Garbage Collection)机制:
- 不同的垃圾回收算法(如标记-清除、复制、标记-整理等)。
- 不同的垃圾回收器(如Serial Collector、Parallel Collector、CMS Collector、G1 Collector等)。
- 内存分配策略,如对象的分配、晋升和移动。
-
性能调优:
- 监控工具(如VisualVM、JConsole等)的使用。
- 堆大小调整、垃圾收集器的选择等配置选项。
- 性能瓶颈定位及优化。
-
线程管理:
- Java线程的状态模型。
- 线程同步机制(如synchronized、volatile等)。
- 死锁检测与避免。
-
内存模型:
- Java内存模型的基础知识。
- volatile关键字的作用。
- 原子性、可见性和有序性。
-
编译与执行:
- 字节码的结构。
- JIT编译器的工作原理。
- 解释器与编译器的结合。
方法区(Method Area)是Java虚拟机(JVM)内存模型中的一个重要组成部分。方法区用于存储已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,以下是关于方法区的一些关键点:
-
存储内容:
- 类信息:包括类名、字段、方法等。
- 常量:类中声明的常量,例如final类型的常量。
- 静态变量:类级别的变量。
- 即时编译后的代码:JIT编译器编译后的本地代码。
- 运行时常量池:类或接口的常量池表存在于方法区中,包含了编译期生成的各种字面量和符号引用。
-
线程共享:
- 方法区是所有线程共享的内存区域,意味着方法区中的数据可以被多个线程访问和使用。
-
持久代(Permanent Generation):
- 在JDK 8之前,方法区被称为永久代(PermGen space)。永久代的大小可以通过JVM参数来设置。
- JDK 8之后,永久代被移除,方法区被移到了本地内存(Native Memory)中,称为元空间(Metaspace)。
-
垃圾回收:
- 方法区中的数据一般较少发生垃圾回收,但并非不可回收。
- 类卸载(Class Unloading)是方法区中可能发生的一种特殊的垃圾回收行为,当类不再被引用时,JVM可能会卸载这些类。
-
内存溢出:
- 如果方法区无法申请足够的内存来存放新加载的类信息等数据,将会抛出
OutOfMemoryError: PermGen space(在JDK 8之前)或OutOfMemoryError: Metaspace(从JDK 8开始)。
- 如果方法区无法申请足够的内存来存放新加载的类信息等数据,将会抛出
-
元空间(Metaspace):
- 从JDK 8开始,方法区被移到了本地内存中,称为元空间。元空间的大小不再受JVM堆大小的限制,而是受限于本地内存。
- 元空间的初始大小可以通过
-XX:MetaspaceSize参数来配置,最大大小可以通过-XX:MaxMetaspaceSize来设定。
总结来说,方法区是用来存储类信息、常量、静态变量等数据的内存区域,它在JVM的内存布局中占有重要的位置。随着JDK版本的变化,方法区的具体实现也发生了变化,但其核心功能保持不变。