jvm

99 阅读4分钟

JVM(Java Virtual Machine)的知识体系可以大致分为以下几个方面:

  1. JVM体系结构:

    • 类加载子系统: 负责加载 .class 文件到JVM中,并将这些内容转换成方法区中的运行时数据结构。
    • 运行时数据区域: 包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区等。
    • 执行引擎: 包含解释器、即时编译器(JIT Compiler)、垃圾回收器等。
  2. 运行时数据区域:

    • 程序计数器(Program Counter Register): 用于记录当前线程所执行的字节码指令的地址。
    • Java虚拟机栈(Java Virtual Machine Stack): 每个线程私有,用于存储局部变量、操作数栈、动态链接、方法出口等信息。
    • 本地方法栈(Native Method Stack): 用于存储Native方法调用的信息。
    • Java堆(Java Heap): 所有线程共享,用于存储对象实例和数组。
    • 方法区(Method Area): 存储已被虚拟机加载的类信息、常量、静态变量等数据。
    • 运行时常量池(Runtime Constant Pool): 是方法区的一部分,用来存放编译期生成的各种字面量和符号引用。
  3. 类加载机制:

    • 类如何被加载、连接和初始化的过程。
    • 类加载器的种类及其层次结构(启动类加载器、扩展类加载器、应用类加载器等)。
    • 双亲委派模型。
  4. 垃圾回收(Garbage Collection)机制:

    • 不同的垃圾回收算法(如标记-清除、复制、标记-整理等)。
    • 不同的垃圾回收器(如Serial Collector、Parallel Collector、CMS Collector、G1 Collector等)。
    • 内存分配策略,如对象的分配、晋升和移动。
  5. 性能调优:

    • 监控工具(如VisualVM、JConsole等)的使用。
    • 堆大小调整、垃圾收集器的选择等配置选项。
    • 性能瓶颈定位及优化。
  6. 线程管理:

    • Java线程的状态模型。
    • 线程同步机制(如synchronized、volatile等)。
    • 死锁检测与避免。
  7. 内存模型:

    • Java内存模型的基础知识。
    • volatile关键字的作用。
    • 原子性、可见性和有序性。
  8. 编译与执行:

    • 字节码的结构。
    • JIT编译器的工作原理。
    • 解释器与编译器的结合。

方法区(Method Area)是Java虚拟机(JVM)内存模型中的一个重要组成部分。方法区用于存储已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,以下是关于方法区的一些关键点:

  1. 存储内容:

    • 类信息:包括类名、字段、方法等。
    • 常量:类中声明的常量,例如final类型的常量。
    • 静态变量:类级别的变量。
    • 即时编译后的代码:JIT编译器编译后的本地代码。
    • 运行时常量池:类或接口的常量池表存在于方法区中,包含了编译期生成的各种字面量和符号引用。
  2. 线程共享:

    • 方法区是所有线程共享的内存区域,意味着方法区中的数据可以被多个线程访问和使用。
  3. 持久代(Permanent Generation):

    • 在JDK 8之前,方法区被称为永久代(PermGen space)。永久代的大小可以通过JVM参数来设置。
    • JDK 8之后,永久代被移除,方法区被移到了本地内存(Native Memory)中,称为元空间(Metaspace)。
  4. 垃圾回收:

    • 方法区中的数据一般较少发生垃圾回收,但并非不可回收。
    • 类卸载(Class Unloading)是方法区中可能发生的一种特殊的垃圾回收行为,当类不再被引用时,JVM可能会卸载这些类。
  5. 内存溢出:

    • 如果方法区无法申请足够的内存来存放新加载的类信息等数据,将会抛出OutOfMemoryError: PermGen space(在JDK 8之前)或OutOfMemoryError: Metaspace(从JDK 8开始)。
  6. 元空间(Metaspace):

    • 从JDK 8开始,方法区被移到了本地内存中,称为元空间。元空间的大小不再受JVM堆大小的限制,而是受限于本地内存。
    • 元空间的初始大小可以通过-XX:MetaspaceSize参数来配置,最大大小可以通过-XX:MaxMetaspaceSize来设定。

总结来说,方法区是用来存储类信息、常量、静态变量等数据的内存区域,它在JVM的内存布局中占有重要的位置。随着JDK版本的变化,方法区的具体实现也发生了变化,但其核心功能保持不变。