JVM内存模型

JAVA通过JVM实现跨平台,在不同平台上允许不同的虚拟机执行同样的字节码文件,来实现跨平台,这是java编译后的代码和机器指令交互的地方,理解JVM有助于在日常工作中避免JVM可能出现的压力及异常,并且可以在项目出现瓶颈时定位问题并解决

JVM区域划分

  1. JVM指令系统

    用来指定需要在目标平台上的操作指令

    1. 操作码 用来执行一条操作的性质
    2. 操作数 紧随操作码之后,被分为两个以上字节
  2. JVM寄存器

    用来保存CPU中包含的保存系统状态和处理信息的寄存器组,减少虚拟机对堆栈的访问,常用的JVM寄存器有四种

    1. PC程序计数器,用于记录程序的执行
    2. optop操作数栈顶指针,用于记录JAVA栈的指针
    3. frame当前执行环境指针,用于记录JAVA栈的指针
    4. vars当前执行环境第一个局部变量指针,用于记录JAVA栈的指针
  3. JVM栈结构
    1. 局部变量 存储类方法中的局部变量
    2. 执行环境 上次调用的方法、局部变量指针、操作数栈、栈底指针
    3. 操作数栈 存储运算所需要的操作数和结果
  4. JVM碎片回收堆
  5. JVM存储区

    1. 常量缓冲池 类名、方法名、常量
    2. 方法区 方法字节码

      JAVA运行时的内存结构

      局部变量表是在编译阶段已经确定的内容,包含已知的基本数据类型,对象引用(指向对象的原始地址或者引用指针、对象句柄、或者用来指向一条字节码指令的returnAddress类型),该区域在方法执行期间不会做出改变大小

  6. 方法区 被所有线程共享,存储加载类时读取的类信息,常量,静态变量以及字节码

  7. JAVA虚拟机栈 每一个线程都会独享一个栈,为虚拟机执行方法进行服务,存储局部变量表、操作数栈、动态链接、方法出口等
  8. JAVA虚拟机堆 被所有线程共享,在虚拟机启动时创建,用于存放对象实例,可以细分为新生代Young和老年代Old,年轻代可以再次划分为Eden、FromSurvivor和ToSurvivor,默认情况下新生代占堆内存的三分之一,随着JIT编译器和逃逸分析的发展,虚拟机可以更好的进行栈上分配和标量替换,所以并不是所有的对象创建都会分配到Heap了
  9. 本地方法栈 每一个线程都会独享一个栈,为虚拟机执行Native方法进行服务,存储局部变量表、操作数栈、动态链接、方法出口等
  10. 程序计数器 每一个线程都会独享一个程序计数器,相互之间不会影响,记录当前字节码的行号指令器

JVM执行程序的过程

  1. 加载Class文件
  2. 管理、分配内存
  3. 进行垃圾回收