• JMM示意图

wKioL1fXY3zTC2y6AACX43wq9-c199.png

  • 运行时数据区

    • 线程私有

      • 程序计数器

        • 一块较小空间,可以看做是线程所执行字节码的行号指示器。

        • 字节码解释器通过计数器的值来获取吓一条需执行的字节码指令,分支、循环、跳转、异常处理线程恢复都需要依赖程序计数器。

        • 如果是Native方法,则计数器为Undefined。

        • 生命周期与线程相同,每个方法执行时,会有一个栈帧。每一个方法执行就是一个栈帧在栈中入栈出栈的过程

        • 如果请求栈深度大于虚拟机所允许的深度,将抛出StackOverFlowException。如果栈动态扩展时无法申请到足够内存,抛出OutOfMemoryError

      • 栈帧

        • 每一个方法执行就是一个栈帧在栈中入栈出栈的过程。

        • 栈帧包含

          • 局部变量表,存放了编译期可知的基本数据类型、对象引用和returnAddress类型-指向了一条字节码地址,所需内存空间在编译时完成分配,运行期间不会改变局部变量表大小。

          • 操作栈,虚拟机在操作栈中保存的数据类型与本地变量一样。Java虚拟机的是基于栈而不是寄存器的。虚拟机把操作数栈作为工作区,数据出栈、计算、结果入栈。

          • 动态连接,编译后的类间通过符号引用互相关联,在方法运行时解析为直接引用,称为动态连接。

          • 返回地址(方法出口信息)

            • 正常退出,会根据方法的定义来决定是否要返回值给调用者。

            • 异常结束,这种情况是不会返回值,虚拟机会调用匹配的异常处理器处理(try……catch),如果没有找到,那么方法会立即结束并弹出当前栈帧,这个异常会被抛出到上层调用者栈帧中。如果所有的栈帧都被弹出还没有找到匹配的 异常处理器,那么这个线程就会终止。如果这个异常在最后一个非守护进程抛出(比如这个线程是主线程),那么也有会导致 JVM 进程终止。

      • 本地程序栈

        • 略。

  • 共享内存

      • 存放对象实例。可以存在物理上不连续,逻辑上连续的内存空间上

    • 方法区

      • 存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等。包括运行时常量池:存放译器生成的字面量和符号引用,这些数据将在类加载后存放到这里。String.intern()也会将常量放这里。

  • 直接内存

    • 不是虚拟机的一部分,NIO中管道和缓冲区都会使用

  • 对象访问

    • 句柄访问-句柄池中保存的句柄包含了对象实例指针和对象类型数据指针

    • 直接指针访问-直接指向对象实例,对象实例中包含了对象类型数据指针(HotSpot使用的是这种)。