JVM基础

JVM基础

什么是JVM(Java Virtual Machine)?

  直接引用《深刻Java虚拟机(原书第二版)》第五章的解释:一、抽象规范;二、一个具体的实现;三、一个运行中的虚拟机实例。个人理解是:首先JVM是一份规范,由Sun公司制订(如今是Oracle公司了),而后针对这个份 规范有多种实现版本,包括Sun和其它公司,运行在操做系统上面是一个具体的实例。数组

为何要了解JVM?

  若是是只是简单的实现增、删、查、改功能或者作demo,确实不须要了解JVM。若是想进一步发掘Java性能、JVM调优、安全等知识,必须了解JVM。安全

JVM的架构?

引用网上图片一张图片,图片源地址:https://dzone.com/articles/jvm-architecture-explained。图片是JVM的逻辑图,自上而下执行;注意顺序和箭头指向;简单来讲:由类型加载器子系统,运行时数据区,即时引擎组成。数据结构

Class Loader Subsystem(类装载子系统)

类装载器子系统除了定位和导入二进制Class文件外,还必须负责验证被导入类的正确性,为类变量分配并并初始化内存,以及帮助解析符号引用。类型包括:类和接口。类装载子系统只识别Class文件,无论Class是怎么生成和建立的。由于不只JAVA语言能够建立Class文件,还有其它语言也能够建立Class文件;其它语言建立的文件只要符合规范就能够被JVM加载、链接、初始化;多线程

  • 装载,使用双亲委派的方式装载类。根据Class路径,查找到对应的Class文件,并导入二进制的Class数据。双亲委派的模式是Java保障安全的的一个重要方法,也是安全特性之一,能够防止恶意代码的被加载;装载的最终产品就是这个Class类的实例对象;
  • 链接,包括三个步骤:验证、准备、解析。验证:确保被导入类型的正确性。能够理解为确认类型符合Java语言的语义,而且不会危及虚拟机的完整性;根据必定规则验证导入Class文件是否符合规范,Class文件的细节是否符合规范;准备:给类变量分配内存,并设置默认值;注意:这里设置默认值是,Java类型的默认值,与代码逻辑没有关系(注意:这个阶段不会执行Java代码)。解析:类型的引用转直接引用(因为Java延迟机制,解析通会延迟到下一阶段进行即:初始化)。
  • 初始化:把类变量正确初始值。要执行JAVA代码逻辑;

在这个装载阶段,有三个点须要搞明白:双亲委派模式、类加载器的命名空间、初始化(主动初始化、被动初始化)。这须要另起一篇文章才能讲清楚,在这里只提一下;架构

一个Class文件必须先被装载后,才获得类型的信息,类型的信息存储于运行时的方法区中,即下面章节要介绍的内容;并发

Runtime Data Area(运行时数据区)

运行时数据区,包含:方法区、堆、栈、程序计数器、本地方法栈;你们即便对JVM不熟悉,也应该知道有堆的存在吧;下面咱们分别看下这些都是干什么的;jvm

  • Method Area(方法区):经过Class Loader装载后获得的类型信息均存储在方法区内,包括类型名称、类型的超类、类型的接口、类型的访问修饰符号、类型的常量池、字段信息、方法信息、方法字节码、异常表、类(静态)变量、编译时常量(使用final以及编译已知道的值初始化的类变量)等信息;实际是把Class文件映射为JVM内部的数据结构,这样JVM才使用执行Class文件逻辑;
  • Heap Area(堆):Java运行时建立的类对象和数组均存储在堆内;一个Java虚拟机实例只有一个堆,该虚拟机实现的全部线程共享堆空间。因为一个Java程序独占一个Java虚拟机实例,因此每一个Java程序都有本身的堆空间;Java程序对于堆的操做是经过New关键去分配空间,但不能手动回收空间(System.gc只是建议JVM进行垃圾回收,何时执行由JVM决定);堆空间回收就是平时你们所理解的垃圾回收,但垃圾回收不只限于堆,也一样适用于方法区;垃圾回收是一个很大课题,须要另起一篇介绍了;JVM的调优的重点也在堆分配和回收策略的制定;
  • Stack Area(栈):启动线程时,在栈区分配一个Java栈;局部变量和引用是存储于线程栈,因此局部变量是不存在并发的问题;
  • 程序计数器:Java程序中的每个线程的PC寄存器,是线程启动时建立的;PC寄存器的大小是一个字长,内容老是线程下一条将被执行指令的"地址";
  • 本地方法栈:略;

运行时数据区应该是你们关注的重点,由于大部分JVM性能调优工做集中在这运行时数据区(也有部分调优的工做是执行引擎作的,因此只能说大部分),特别垃圾机制对堆、方法区的影响;另外,平时你们没有依据的增长堆内存或者栈内存,基本是都是无效的,或者是错误的;为何这么说,须要另篇文章才说得清楚;性能

Execution Engine(执行引擎)

Execution Engine(执行引擎)就是行为就是执行指令集合,具体实现JVM规范定义的指令;直接和本地操做交互;执行引擎可使用多种执行技术:解释、即时编译、自适应优化等;自适应优化是目前执行引擎使用普遍的技术。测试

自适应优化的虚拟机开始时候都是解释运行的,可是它会监视执行状况。它会自动识别那些是程序"热区",而后把"热区"代码编译成本地代码,很是仔细地优化这些代码,以达更好性能要求。因此平时压力测试时,要先让程序跑一会,才能达到执行引擎的正常的状态。优化

Java线程模型

Java虚拟机规范定义的线程模型,目标是有助于在很体系结构上都实现它,在可能的状况下使用本地线程。使用本地线程的好处就是,Java线程能够不一样的处理器上并行工做。关于线程的内容也很大,这里只有备忘下,有时间另起一篇文章介绍。

  • 虚拟规范没有假设不一样优先级的线程采用时间分片方式。因此在不一样体系的JVM所实现的分片方式是不同的,多线程的程序不能依赖线程优先级。
  • 虚拟机的规范中,Java的线程行为术语是经过-变量、主存、和工做内存,来定义的。因此咱们上面介绍JVM没有出现过主存、工做内存的术语,是由于这是虚拟机规范的用语,具体映射到JVM时有更详细的术语和说法。但这并非说,虚拟机规范和实现不统一,虚拟机规范只是规定虚拟机要实现的功能,并不关心虚拟机怎么实现。这是我刚开始学JVM很困惑的地方,由于网上不少都说JVM的内存模型,实际上是线程模型,线程模型包含了主存和工做内存的工做方式。
  • Java虚拟机规范定义许多规则用来管理线程和主存之间的低层交互行为。基本上,管理低层的行为规则能够解读为:
  1. 把变量的值从主存拷贝到它的工做内存。
  2. 把值从它的工做内存写回主存。

与线程模型有密切关系的Java关键字volatile,感兴趣的能够本身了解下。或者回复评论,我进一步解释。由于这个与虚拟机不太相关了。

相关文章
相关标签/搜索