星球狂想战队|清华扫地僧带你深入JVM调优实战,思路清晰,精通简直太容易( 二 )


2.3.2 执行引擎执行引擎是 Java 虚拟机最核心的组成部分之一 。 “虚拟机” 是一个相对于 “物理机” 的概念 , 这两种机器都有代码执行能力 , 其区别是物理机的执行引擎是直接建立在处理器、硬件、指令集和操作系统层面上的 , 而虚拟机的执行引擎则是由自己实现的 , 因此可以自行制定指令集与执行引擎的结构体系 , 并且能够执行哪些不被硬件直接支持的指令集格式 。
所谓的「虚拟机字节码执行引擎」其实就是 JVM 根据 Class 文件中给出的字节码指令 , 基于栈解释器的一种执行机制 。 通俗点来说 , 也就是 JVM 解析字节码指令 , 输出运行结果的一个过程 。
2.4 JVM的运行时数据区先通过两张结构图 , 了解一下不同版本下的运行时数据区的结构!
1.8版本之后的结构图如下:
星球狂想战队|清华扫地僧带你深入JVM调优实战,思路清晰,精通简直太容易1.8版本之前的结构图如下:
星球狂想战队|清华扫地僧带你深入JVM调优实战,思路清晰,精通简直太容易JVM中 , 运行时数据区具体是什么?带着这个疑问 , 咱们通过下面这张图详细了解一下:
星球狂想战队|清华扫地僧带你深入JVM调优实战,思路清晰,精通简直太容易看似复杂 , 其实咱们大致先分为几个部分来理解 。 上图可分为两大类型:共享区域与非共享区域 。 图中左侧都是所有线程共享的区域 , 右侧为每个线程私有的区域 。
2.4.1 共享区域堆(heap)所有类的实例就放在这个区域 , 为所有线程共享 。 可以想象你的一个系统会产生很多实例 , 因此Java堆的空间也是最大的 。 如果Java堆空间不足了 , 程序会抛出OutOfMemoryError异常 。
方法区各个线程共享的区域 , 存放类信息、常量、静态变量 。
2.4.2 非共享区域程序计数器指向当前线程正在执行的字节码的地址 和行号(指令都是在cpu上面运行的 , 分配到时间片才去运行的 , 当多个线程的时候其他线程会被挂起 , 程序计数器就是记录被挂起之前的字节码执行到哪行 地址等 , 等到重新分配到了时间片然后再继续执行) 。 它的作用就是控制程序指令的执行顺序 。
虚拟机栈存储当前线程运行方法所需要的数据 , 指令 , 返回的地址
每个线程创建的同时会创建一个JVM栈 , JVM栈中每个栈帧存放的为当前线程中局部基本类型的变量、部分的返回结果 , 非基本类型的对象在JVM栈上仅存放一个指向堆上的地址 。
而每个栈帧中 , 又包含如上图中的:局部变量表 , 操作数栈 , 动态链接 , 方法出口 , 具体作用如图所解释 。
本地方法栈本地方法栈是用来存储本地方法相关的数据 。 本地方法就是带有native标识符修饰的方法;
native修饰符修饰的方法并不提供方法体 , 但因为其实现体是由非java代码在在外部实现的 , 因此不能与abstract连用;
存在的意义:不方便用java语言写的代码 , 使用更为专业的语言写更合适;甚至有些JVM的实现就是用c编写的 , 所以只能使用c来写
2.4.3 JMM(java内存模型)通过一张图来认识JMM的内部结构:
星球狂想战队|清华扫地僧带你深入JVM调优实战,思路清晰,精通简直太容易