Java规范定义标准结构如图3.1

  1. Java代码的执行机制

Java源码编译机制

javac将Java源码编译为class文件的步骤如图3.2

1.分析和输入到符号表(Parse and Enter)

Parse过程所做的为词法和语法分析。词法分析(com.sun.tools.javac.parser.Scanner)要完成的是将代码字符串转变为token序列(例如Token.EQ(name:=));语法分析(com.sun.tools.javac.parser.Parser)要完成的是根据语法由token序列生成抽象语法树。

  1. 注解处理(Annotation Processing)

该步骤主要用于处理用户自定义的annotation。

  1. 语义分析和生成class文件(Analyse and Generate)

Analyse步骤基于抽象语法树进行一系列的语义分析。

类加载机制

类加载机制是指.class文件加载到JVM,并形成Class对象的机制,之后应用就可对Class 对象进行实例化并调用,类加载机制可在运行时动态加载外部的类、远程网络下载过来的class 文件等。除了该动态化的优点外,还可通过JVM的类加载机制来达到类隔离的效果。

JVM将类加载过程划分为三个步骤:装载、链接和初始化。装载和链接过程完成后,即将二进制的字节码转换为Class对象;初始化过程不是加载类时必须触发的,但最迟必须在初次主动使用对象前执行,其所作的动作为给静态变量赋值、调用<clinit>()等。

1.装载(Load)

装载过程负责找到二进制字节码并加载至JVM 中,JVM通过类的全限定名(com.bluedavy.HelloWorld)及类加载器(ClassLoaderA实例)完成类的加载。

2.链接(Link)

链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量及解析类中调用的接口、类。

3.初始化(Initizlize)

初始化过程即执行类中的静态初始化代码、构造器代码及静态属性的初始化,在以下四种情况初始化过程会被触发执行:

1)调用了new;

2)反射调用了类中的方法;

3)子类调用了初始化;

4)JVM启动过程中指定的初始化类。

类执行机制

字节码解释执行

在源码编译阶段将源码编译为JVM字节码,JVM字节码是一种中间代码的方式,要由JVM在运行期对其进行解释并执行,这种方式称为字节码解释执行方式。

  1. 指令解释执行

指令解释执行即获取下一条指令,解码并分派,然后执行。

  1. 栈顶缓存

栈顶缓存,即将本来位于操作数栈顶的值直接缓存在寄存器上,这对于大部分只需要一个值的操作而言,无须将数据放入操作数栈,可直接在寄存器计算,然后放回操作数栈。

  1. 部分栈帧共享

当调用方法时,后一方法可将前一方法的操作数栈作为当前方法的局部变量,从而节省数据copy带来的消耗。

编译执行

解释执行的效率较低,为提升代码的执行性能,Sun JDK提供将字节码编译为机器码的支持,编译在运行时进行,通常称为JIT编译器。Sun JDK在执行过程中对执行频率高的代码进行编译,对执行不频繁的代码则继续采用解释的方式,因此Sun JDK又称为Hotspot VM,在编译上Sun JDK提供了两种模式:client compiler (-client)和server compiler ( -server)。

client compiler又称为C1,较为轻量级,只做少量性能开销比高的优化,它占用内存较少,适合于桌面交互式应用。在寄存器分配策略上,JDK6以后采用的为线性扫描寄存器分配算法,在其他方面的优化主要有:方法内联、去虚拟化、冗余削除等。

  1. 方法内联

对于Java类面向对象的语言,通常要调用多个方法来完成功能。执行时,要经历多次参数传递、返回值传递及跳转等,于是C1采取了方法内联的方式,即把调用到的方法的指令直接植入当前方法中。

  1. 去虚拟化

去虚拟化是指在装载class文件后,进行类层次的分析,如发现类中的方法只提供一个实现类,那么对于调用了此方法的代码,也可进行方法内联,从而提升执行的性能。

  1. 冗余削除

冗余削除是指在编译时,根据运行时状况进行代码折叠或削除。

Server compiler又称为C2,较为重量级,C2采用了大量的传统编译优化技巧来进行优化,占用内存相对会多一些,适合于服务器端的应用。和C1不同的主要是寄存器分配策略及优化的范围,寄存器分配策略上C2采用的为传统的图着色寄存器分配算法“;由于C2会收集程序的运行信息,因此其优化的范围更多在于全局的优化,而不仅仅是一个方法块的优化。收集的信息主要有:分支的跳转/不跳转的频率、某条指令上出现过的类型、是否出现过空值、是否出现过异常。

逃逸分析是C2进行很多优化的基础,逃逸分析是指根据运行状况来判断方法中的变量是否会被外部读取。如不会则认为此变量是逃逸的,基于逃逸分析C2在编译时会做标量替换、栈上分配和同步削除等优化。除了逃逸分析以外,C2还会基于其拥有的运行信息来做其他的优化,例如编译分支频率执行高的代码。

  1. 标量替换

标量替换的意思简单来说就是用标量替换聚合量。

  1. 栈上分配

如果对象没有逃逸,那么C2会选择在栈上直接创建Point对象实例,而不是在JVM堆上。

  1. 同步削除

同步削除是指如果发现同步的对象未逃逸,那也没有同步的必要了,在C2编译时会去掉同步。

OSR (On Stack Replace)编译。OSR编译和C1、C2最主要的不同点在于OSR编译只替换循环代码体的入口,而C1、C2替换的是方法调用的入口,因此在OSR编译后会出现的现象是方法的整段代码被编译了,但只有在循环代码体部分才执行编译后的机器码,其他部分则仍然是解释执行方式。

反射执行

基于反射可动态调用某对象实例中对应的方法、访问查看对象的属性等,无需在编写代码时就确定要创建的对象。反射和直接创建对象实例,调用方法的最大不同在于创建的过程、方法调用的过程是动态的。

使用反射执行可以获取类的成员变量(包括私有成员变量)。

JVM内存状况查看方法和分析工具

几种常用的工具:输出GC日志、GC Port、JConsole、JVisuaIVM、JMap、JHat、JSat、Eclipse Memory Analyzer

2.JVM线程资源同步及交互机制

线程资源同步机制、线程资源交互机制

线程状态及分析

JVM把线程分为几种不同的状态,并根据状态放入不同的sets 中来进行调度。线程在创建完毕后进入new状态,调用了线程的start方法后线程进入Runnable状态,放入JVM的可运行线程队列中,等待获取CPU 的执行权;JVM按线程优先级及时间分片、轮循的方式来执行Runnable状态的线程。当线程进入start代码段,开始执行时,其线程状态转变为Running;线程在执行过程中如果执行了sleep,wait、join,或者进入了IO阻塞、锁等待时,则进入Wait或Blocked 状态,在这种状况下线程放弃CPU的使用权,进入 wait sets或锁sets中,直到wait结束、线程被唤醒或获取到锁,在这些情况下线程也再次进入Runnable状态;在线程执行完毕后,线程就从可运行线程队列中删除了,JVM线程的状态转变如图3.24所示。

深入理解JVM之代码执行机制与线程资源同步及交互机制相关推荐

  1. 深入理解JVM虚拟机(十一):线程安全与锁优化

    1. 线程安全 线程安全的定义:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方法进行任何其他的协调操作,调用这个对象的行为都可以获得 ...

  2. 【JVM技术专题】较为深入分析线程池基本原理及实现机制「 入门篇」

    基本原理 线程池基本常识 线程池(Thread Pool)是一种基于池化思想管理线程的工具.线程频繁的创建.销毁会产生大量的系统内核调用,消耗CPU资源.用线程池来维护多个线程的生命周期,一方面可以避 ...

  3. jvm体系结构_JVM体系结构:JVM中的执行引擎

    jvm体系结构 各位读者好! 在JVM系列的上一篇文章中,开发人员了解了虚拟机的ClassLoader和Runtime Data Areas组件. 本教程将帮助开发人员正确理解JVM中的执行引擎 . ...

  4. JVM体系结构:JVM中的执行引擎

    各位读者好! 在JVM系列的上一篇文章中,开发人员了解了虚拟机的ClassLoader和Runtime Data Areas组件. 本教程将帮助开发人员正确理解JVM中的执行引擎 . 1.简介 在继续 ...

  5. 「Vue 学习笔记 1」Vue 项目快速搭建,初始项目各个文件夹作用介绍和启动代码执行流程分析

    「Vue 学习笔记 1」Vue 项目快速搭建,初始项目各个文件夹作用介绍和启动代码执行流程分析 前言 一.我的开发环境 二.使用 Vue CLI (Vue 脚手架)快速搭建项目 三.初始项目的目录结构 ...

  6. 【深入理解JVM】ClassLoader类加载机制

    Java程序并不是一个原生的可执行文件,而是由许多独立的类文件组成,每一个文件对应一个Java类.此外,这些类文件并非立即全部装入内存的,而是根据程序需要装入内存.ClassLoader专门负责类文件 ...

  7. jvm垃圾回收机制_深入理解JVM的垃圾回收机制

    ​如何判断对象已"死" Java堆中存放着几乎所有的对象实例,垃圾回收器在堆进行垃圾回收前,首先要判断这些对象那些还存活,那些已经"死去".判断对象是否已&qu ...

  8. 深入理解JVM垃圾收集机制(JDK1.8)

    垃圾收集算法 标记-清除算法 最基础的收集算法是"标记-清除"(Mark-Sweep)算法,分两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象. 不足: ...

  9. jvm大局观之内存管理篇: 理解jvm安全点,写出更高效的代码

    jvm大局观之内存管理篇: 理解jvm安全点,写出更高效的代码 - 知乎 前言 本篇是java内存区域管理系列教程之一 - 在得知GC Root的组成之后,如何在垃圾回收发生的时刻,找到GC Root ...

最新文章

  1. OWA修改密码注意事项
  2. js传参不是数字_js调用函数时传入的参数个数与函数定义时的参数个数不符时的操作...
  3. repo一个新工程使用步骤
  4. 如何使用会声会影标题工具制作弹幕效果
  5. 【机房运维】网格机房机柜、机架内的空间规划及理线方法
  6. c语言int占几个字节 vc,int类型占几个字节
  7. win10无法被远程计算机,win10无法被远程连接解决方法
  8. mac安装搜狗输入法
  9. html测试身高体重,【 身高体重测试】_如何测试_注意事项-大众养生网
  10. 【报告分享】2021B站创作者生态报告-哔哩哔哩(附下载)
  11. inno setup 卸载注册表_inno setup 修改卸载文件名称
  12. android端向后台传图片,Android前台从后台下载一张图片 以及 Android前台上传一张图片到后台...
  13. 一起来乐邮邮——妙趣小软件:MailMail发布预告
  14. Kruskal 算法介绍
  15. tankgame网络版开发
  16. JavaScript基础知识梳理
  17. C语言 进制转换(1-16进制)
  18. 综合中央计算机系统简称,广州地铁TVM本地数据与SC报表数据不一致故障分析研究...
  19. python实现累乘multi函数(函数参数不限)
  20. Python第三方库(模块)下载和安装(使用pip命令)

热门文章

  1. 性能分析神器VisualVM
  2. 菲律宾邀请姚明率队访菲打友谊赛
  3. Java网络爬虫-总结
  4. Matlab 2021a 安装教程(手把手式教程)
  5. Ajax服务器415错误,弹簧休息时ajax发布时出现415错误
  6. Redis实战高并发,由浅入深
  7. Redis命令之散列
  8. 有什么比较好的半入耳式蓝牙耳机,半入耳无线耳机排行榜
  9. 一个简单的网站首页制作
  10. 台式电脑电源有电却无法开机怎么办