汇编

汇编的目的是把汇编语言转为机器语言。

链接

链接是要解决目标文件之间的互相依赖关系,当a文件中的aa方法中调用了b文件的bb方法时,在汇编完成后,a文件的bb方法并没有准确的内存地址,链接后会转换为虚拟地址,虚拟地址可以依据一定的规则转换为实际地址,即可以运行时找到该方法。

编译过程

一个.java程序要想被执行,首先需要编译器将高级的.java程序文件编译成.class字节码片段。编译过程大致可以分为1个准备过程和3个处理过程

  1. 准备过程:初始化插入式注解处理器。

  2. 解析与填充符号表过程,包括:词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树。填充符号表。产生符号地址和符号信息。

  3. 插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段。

  4. 分析与字节码生成过程,包括

    • 标注检查。对语法的静态信息进行检查。

    • 数据流及控制流分析。对程序动态运行过程进行检查。

    • 解语法糖。将简化代码编写的语法糖还原为原有的形式,(Java虚拟机运行时并不直接支持这些语法,它们在编译阶段被还原回原始的基础语法结构,这个过程就称为解语法糖。)

    • 字节码生成。将前面各个步骤所生成的信息转化成字节码。

上述3个处理过程里,执行插入式注解时又可能会产生新的符号,如果有新的符号产生,就必须转回到之前的解析、填充符号表的过程中重新处理这些新符号。

常见语法糖

  1. 泛型(泛型擦除)

  2. switch 支持 String(其实比较的是hashcode是否相等)

  3. for each循环

  4. lambda表达式

  5. 自动装箱拆箱(valueOf方法)

  6. 可变长度参数(转换为数据)

  7. 枚举

  8. 内部类

  9. 条件编译

  10. 断言

  11. 数值字面量10_0000

  12. try with source

运行阶段

字节码经过JVM(解释器)的处理后生成电脑可以直接执行的机器码,至此java程序才能得以正确运行。编译器无论在何时、在何种状态下把Class文件转换成与本地基础设施(硬件指令集、操作系统)相关的二进制机器码,它都可以视为整个编译过程的后端.

编译器

目前主流的两款商用Java虚拟机(HotSpot、OpenJ9)里,Java程序最初都是通过解释器进行解释执行的,当虚拟机发现某个方法或代码块的运行特别频繁,就会把这些代码认定为“热点代码”,为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成本地机器码,并以各种手段尽可能地进行代码优化,运行时完成这个任务的后端编译器被称为即时编译器。

编译的触发条件

HotSpot是采用基于计数器的热点检测,虚拟机会为每个方法(甚至是代码块)建立计数器,统计方法的执行次数,如果执行次数超过一定的阈值就认为它是“热点方法”。

编译器模式

混合模式(默认)

解释器interpreter

编译器JIT

解释执行

    会逐条的将字节码转换成机器码然后执行。

编译执行

    先将左右的字节码编译成机器码然后执行。

混合模式

解释代码中有大量重复的时候可以将其编译到本地(热点代码检测)热点代码检测

  • 多次调用的方法:方法计数器,监测方法执行频率

  • 多次调用的循环:循环计数器,检测循环执行频率

参数设置

-Xmixed:默认为混合模式

-Xint 使用解释模式,执行稍慢,启动很快

-Xcomp 使用纯编译模式,执行很快,启动很慢

从加载到运行

加载

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。

  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为这个类的各种数据的访问入口。

验证

    确保字节码文件数据是否为符合jvm虚拟机可识别的格式。包括文件格式、字节码格式、元数据和符号引用验证。

准备

为类变量赋值为初始化值,实例变量不赋值。如果被final修饰,则会编程常量,在编译的时候就已经存在。所以在这里会显示的初始化。

解析

    将常量池中的符号引用转换成对应的直接引用。在字节码文件中可以看到这个常量。

初始化:执行类构造器的方法。

public class TestClInit {    private static int num = 1;    static {        num = 2;    }    public static void main(String[] args) {        System.out.println(num);    }}

图片中执行clinit方法的位置,先后定义一个常量1,2执行putstatic操作。

init vs clinit

    init是instance实例构造器,对非静态变量解析初始化,而clinit是class类构造器对静态变量,静态代码块进行初始化。

主动使用vs被动使用

    如果调用了clinit方法,就是主动使用。

主动使用场景

    -XX +TraceClassLoading 跟踪类的加载信息

  1. 使用new、反射、clone、反序列化等关键词。

  2. 主动调用类的静态方法,即执行invokestatic指令。方法本身是不会出现在clinit里面。

  3. 使用类、接口中的静态字段(非final)。

  4. 使用reflect反射包方法。

  5. 在初始化子类时,如果父类还没有初始化,则会执行父类的clinit方法,但是不适用于接口,如果实现某个接口,并不会对该接口进行初始化。

  6. main方法。

  7. 接口中的default方法,如果直接实现或间接实现类进行初始化,那么该接口先初始化。

被动使用场景:没有初始化,不意味着没有加载

  1. 通过子类去访问父类的静态字段,只会初始化父类而子类不会进行初始化。

  2. 通过数组定义类的引用,不会进行初始化。

    User[] users = new User[10];  User[0] user = new User();//在这里才会初始化
  3. 引用private static final  NUM= 1;常量不会触发类或接口的初始化,在准备阶段已经赋值。

    //如果是要在初始阶段Random 初始化完成重新赋值,那么就会触发类的初始化。private static final  NUM= new Random().nextInt(10);
  4. 使用ClassLoader的loadClass方法,也不会触发初始化。

类的卸载(方法区的垃圾回收)

回收常量池中废弃的常量和不再使用的引用类型

  1. 类和接口全限定名

  2. 方法的名称和描述符

  3. 字段的名和描述符

只要该常量没有被引用,就会被回收。和回收堆中对象类似。

如何判断类不被使用的3个条件。

  1. 该类的所有实例被回收,包括类的子类的实例也不存在。

  2. 加载该类的类加载器也被回收。

  3. 类对应的Class也没有被引用过,在反射的时候会使用。

如果不执行该回收操作,那么就会有可能发生OOM当类的对应的Class对象结束生命周期,那么就不会再指向方法区中的二进制数据, 那么该对象的生命周期才会结束,才会执行后面的方法区垃圾回收。因此回收的必要条件是Class对象相关联的所有指针都被切断。条件比较苛刻,主要是在于加载器的卸载难度较大:

  1. 启动类加载器和扩展类加载器在运行期间是不可能被卸载。

  2. 自定义加载器只有在上下文环境比较简单,才会有可能被卸载。

linux java运行class文件_jvm学习java文件运行过程相关推荐

  1. Java到底是什么?学习java可以做什么呢?

    Java到底是什么?在互联网信息高速发展的时代,java技术的应用无处不在,网页.手机系统.软件.游戏等这些成果展现在我们面前,有java的功劳.综上可看出java的应用非常广,与其相应的工作岗位就多 ...

  2. 学习java可以做什么?学习java有什么用?

    学习java可以做什么?学习java有什么用?Java不仅是时下最火的编程语言,还是一门很年轻的语言.Java已成为当今市面上最受欢迎的编程软件,对于处于信息高速发达的今天,Java技术已经无处不在, ...

  3. java初学者应该怎么去学习java?java学习流程

    Java是目前热门的编程语言之一,应用范围广泛,竞争很大,并且人员需求稳定.java初学者应该怎么去学习java才好?java初学者看什么书?本篇来谈谈这个问题. java初学者应该怎么去学习java ...

  4. Java培训:什么是Java?为什么大家都学习Java技术?

    java技术在互联网行业属于常驻嘉宾,想要进入到互联网行业,学习java技术是首选,那么具体什么是java?为什么大家都学习java技术?来看看下面的详细介绍就知道了. 1. 什么是java? Jav ...

  5. 学习java的心得体会_学习java的心得体会范文.doc

    学习java的心得体会范文 篇一:JAVA学习的心得体会 ? 国家队每一次踢球失败后都要说这么一句:我们回去后要好好总结,下次会打得更好! ? 总结不代表就能改过原有的不足,也不代表就能进步了 ? ( ...

  6. java 本地方法栈_JVM学习笔记-本地方法栈(Native Method Stacks)

    本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native ...

  7. java编程学习方法_在线学习Java编程的最佳方法

    java编程学习方法 1.简介 Java是使用最广泛的编程语言之一. 根据Github的最新报告 ,Java被列为仅次于JavaScript的第二大最常用的编程语言. 掌握Java的人有很多话题. 好 ...

  8. linux底层文件io,学习Rust 文件与 IO

    导读 Rust 语言是一种高效.可靠的通用高级语言.其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言. 本章介绍 Rust 语言的 I/O 操作. 接收命令 ...

  9. 6种java垃圾回收算法_学习java垃圾回收

    垃圾回收(GC)一直是Java受欢迎背后的重要特性之一.垃圾回收是Java中用于释放未使用的内存的机制.本质上,它追踪所有仍在使用的对象,并将剩下的标记为垃圾.Java的垃圾回收被认为是一种自动内存管 ...

最新文章

  1. SaaS到底是什么,如何做?这份笔记讲明白了
  2. Eclipse+Maven创建webapp项目
  3. python 封装_Python 面向对象三大特性之封装
  4. CentOS安装和配置Rsync进行文件同步
  5. labelme实例分割_MaskRCNN在多个实例数据集上实践
  6. Bezier(贝塞尔)曲线(五阶)的轨迹规划在自动驾驶中的应用(六)
  7. ADO.NET远程访问Access数据库的连接字符串
  8. 每日吃三颗红枣,对我们的身体有什么影响?
  9. 米勒罗宾素数判定(模板)
  10. Android 折线图(MPAndroidChart框架)
  11. 数据可视化插件 echart
  12. 从零开始学编程之我见
  13. 在线Cron表达式生成器,定时任务表达式生成器
  14. 从零开始学习鸿蒙系统
  15. fgo服务器中断020202,fgo2.6版本更新 8月18日更新维护内容一览
  16. 计算机信息安全培训简报,以训促防 筑牢网络信息安全 我局举办网络信息安全培训...
  17. HCIA-IoT 个人学习总结 Day4
  18. 企业提高客户保持率基本方法
  19. 一次悲惨的被挖矿经历
  20. java获取word图片_java代码获取word文件中的图片

热门文章

  1. Ubuntu16.04安装boost库
  2. 数据挖掘:数据清洗——异常值处理
  3. 12-matlab简单读excel
  4. format 用法及对齐
  5. 白鹭引擎 - 矢量绘图 ( graphics )
  6. 斐波那契数列的递归与迭代写法比较
  7. ATT汇编针对x86指令集格式
  8. php使用imagick进行图像处理
  9. CCF201409-1 相邻数对(100分)【序列处理】
  10. UVA10194 Football (aka Soccer)【排序】