博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JVM原理和调优
阅读量:6980 次
发布时间:2019-06-27

本文共 2600 字,大约阅读时间需要 8 分钟。

hot3.png

什么是JVM?


JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的

Java 语言的一个非常重要的特点就是与平台的无关性。而使用 Java 虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入 Java 语言虚拟机后,Java 语言在不同平台上运行时不需要重新编译。Java 语言使用 Java 虚拟机屏蔽了与具体平台相关的信息,使得 Java 语言编译程序只需生成在 Java 虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java 虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是 Java 的能够 "一次编译,到处运行" 的原因

从图中很清晰的等看到平台结构以及 JDK、JRE、JVM 三者的关系

从上图我们可以看到 JVM 的工作流程

编译和执行流程


javac 是一种编译器,能将一种语言规范转化成另外一种语言规范,通常编译器都是将便于人理解的语言规范转化成机器容易理解的语言规范,如 C/C++ 或者汇编语言都是将源代码直接编译成目标机器码,这个目标机器代码是 CPU 直接执行的指令集合,这些指令集合也就是底层的一种语言规范

javac 的任务就是将 javac 源代码编译成 JVM 能是别的 字节码文件,从表面看是将 .java 文件转化为 .class 文件。而实际上是将 java 源代码转化成一连串二进制数字,这些二进制数字是有格式的,只有JVM能够真确的识别他们到底代表什么意思

步骤:

  1. 词法分析:读取源代码,一个字节一个字节的读进来,找出这些词法中我们定义的语言关键词如:if、else、while等,识别哪些 if 是合法的哪些是不合法的。这个步骤就是词法分析过程

  2. 词法分析的结果:就是从源代码中找出了一些规范化的token流,就像人类语言中,给你一句话你要分辨出哪些是一个词语,哪些是标点符号,哪些是动词,哪些是名词

  3. 语法分析:就是对词法分析中得到的token流进行语法分析,这一步就是检查这些关键词组合在一起是不是符合 java 语言规范。如 if 的后面是不是紧跟着一个布尔型判断表达式

  4. 语法分析的结果:就是形成一个符合 java 语言规定的抽象语法树,抽象语法树是一个结构化的语法表达形式,它的作用是把语言的主要词法用一个结构化的形式组织在一起。这棵语法树可以被后面按照新的规则再重新组织

  5. 语义分析:语法分析完成之后也就不存在语法问题了,语义分析的主要工作就是把一些难懂的,复杂的语法转化成更简单的语

  6. 语义分析结果:就是将复杂的语法转化为简单的语法,对应到 java 就是将 foreach 转化为 for 循环,还有一些注释等。最后生成一棵抽象的语法树,这棵语法树也就更接近目标语言的语法规则

  7. 字节码生成:将会根据经过注释的抽象语法树生成字节码,也就是将一个数据结构转化为另外一个数据结构。就像将所有的中文词语翻译成英文单词后按照英文语法组装文英文语句。代码生成器的结果就是生成符合 java 虚拟机规范的字节码

最后生成的 class 文件由以下部分组成:

  • 结构信息:包括 class 文件格式版本号及各部分的数量与大小的信息
  • 元数据:对应于 java 源码中声明与常量的信息。包含类/继承的超类/实现的接口的声明信息、域与方法声明信息和常量池
  • 方法信息:对应 java 源码中语句和表达式对应的信息。包含字节码、异常处理器表、求值栈与局部变量区大小、求值栈的类型记录、调试符号信息

名词释义:

  • token 流:就是将代码字符串转换为接下来语法分析的最小单位字符序列
  • 符号表: 符号表是一种用于语言翻译器(例如编译器和解释器)中的数据结构。在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如其数据类型、作用域以及内存地址。 符号表在编译程序工作的过程中需要不断收集、记录和使用源程序中一些语法符号的类型和特征等相关信息。这些信息一般以表格形式存储于系统中。如常数表、变量名表、数组名表、过程名表、标号表等等,统称为符号表。对于符号表组织、构造和管理方法的好坏会直接影响编译系统的运行效率

类加载机制


JVM 的类加载是通过 ClassLoader 来完成的,类的层次关系和加载顺序可以由下图来描述:

  1. Bootstrap ClassLoader:负责加载 $JAVA_HOME 中 jre/lib/rt.jar 里所有的 class,由 C++ 实现,不是ClassLoader 子类

  2. Extension ClassLoader:负责加载 java 平台中扩展功能的一些jar包,包括 $JAVA_HOME 中 jre/lib/*.jar 或 -Djava.ext.dirs 指定目录下的jar包

  3. App ClassLoader:负责记载 classpath 中指定的 jar 包及目录中 class

  4. Custom ClassLoader:属于应用程序根据自身需要自定义的 ClassLoader,如 tomcat、jboss 都会根据 j2ee 规范自行实现 ClassLoader 加载过程中会先检查类是否被已加载,检查顺序是自底向上,从 Custom ClassLoader 到 BootStrap ClassLoader 逐层检查,只要某个 ClassLoader 已加载就视为已加载此类,保证此类只所有 ClassLoader 加载一次。而加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类

类执行机制


JVM 是基于栈的体系结构来执行 class 字节码的。线程创建后,都会产生程序计数器(PC)和栈(Stack),程序计数器存放下一条要执行的指令在方法内的偏移量,栈中存放一个个栈帧,每个栈帧对应着每个方法的每次调用,而栈帧又是有局部变量区和操作数栈两部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈中用于存放方法执行过程中产生的中间结果。栈的结构如下图所示:

JVM 调优总结


转载于:https://my.oschina.net/zhoumj/blog/3046656

你可能感兴趣的文章
Python全栈开发day2
查看>>
python开发环境搭建
查看>>
c++ 普通高精减
查看>>
(二十一)数组的初始化
查看>>
IHttpHandler 在SharePoint中的应用
查看>>
c# 关闭软件 进程 杀死进程
查看>>
swift集成alamofire的简单封装
查看>>
javascript模块化、模块加载器初探
查看>>
每天工作4小时的程序员【转】
查看>>
替换空格
查看>>
css中的垂直居中方法
查看>>
android上line-height的问题
查看>>
php相关书籍视频
查看>>
java web项目流程小结
查看>>
PL/SQL Developer远程访问Oracle数据库
查看>>
Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
查看>>
细说浏览器特性检测(2)-通用事件检测
查看>>
完美数据迁移-MongoDB Stream的应用
查看>>
二、JavaScript基础 学好jQuery要了解的
查看>>
Hibernate之继承映射
查看>>