什么是Java虚拟机?

要弄明白Java程序的执行过程首先要了解一下Java虚拟机

虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

Java虚拟机(Java Virtual Machine简称JVM)是运行所有Java程序的抽象计算机,是Java语言的运行环境,它是Java 最具吸引力的特性之一。--百度百科

可以看到,Java虚拟机是在原有计算机的基础上虚拟出来的抽象计算机,提供Java程序的运行环境。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM是Java平台无关的基础,使Java程序能够做到 “Write Once, Run Anywhere”。

Java程序执行过程

那有了Java程序的运行环境等一些列支持后,Java程序是如何做到从一个只有代码的.java源文件变成计算机可执行的文件的呢? 如下图,是Java程序的执行过程。

大致过程就是,我们写好的.java文件(源文件)被编译器编译后变成.class文件(字节码),然后被JVM的类加载器加载到内存,通过字节码校验器去做一些校验,校验通过后交由解释器将字节码文件解释成计算机能够识别的机器指令。

维基百科

字节码:字节码是已经经过编译,但与特定机器码无关,需要解释器转译后才能成为机器码的中间代码。

Java字节码:是Java虚拟机执行的一种指令格式。

解释器:是一种电脑程序,能够把高级编程语言一行一行直接翻译运行。解释器不会一次把整个程序翻译出来,只像一位“中间人”,每次运行程序时都要先转成另一种语言再作运行,因此解释器的程序运行速度比较缓慢。它每翻译一行程序叙述就立刻运行,然后再翻译下一行,再运行,如此不停地进行下去。它会先将源码翻译成另一种语言,以供多次运行而无需再经编译。其制成品无需依赖编译器而运行,程序运行速度比较快

通过上图我们知道Java程序的执行会经过一下几个步骤:​编译-->装载字节码-->校验字节码-->解释字节码-->执行,然后我们看一下这几个步骤具体执行过程,以及Java程序的执行过程对应到我们的实际操作:

1、编译

在windows环境中,打开命令窗口,切换到java文件的目录,使用 javac 命令,执行 javac xxx.java 把.java文件编译成.class文件

2、装载字节码

编译好的.class文件交给 JVM 执行,即使用java命令,执行java xxx(.class文件的名称,不带后缀)。java命令将会启动 JVM,并将后面的参数作为初始化类,通过 JVM 内的类加载器将字节码文件装载到内存中。

3、校验字节码

类的加载是通过类加载器进行的,加载完后,先由字节码校验器负责检查那些无法执行的明显有破坏性的操作。除了系统类之外,其他类都要被校验。

校验器执行的一些检查:

  • 变量要在使用前初始化

  • 方法调用与对象引用类型之间要匹配

  • 访问私有数据和方法的规则没有被违反

  • 对本地变量的访问都在运行的堆栈内

  • 运行时堆栈没有溢出

如果这些检查没有通过,类最终不会被加载完成。

4、解释字节码

JVM 把每一条要执行的字节码交给解释器,翻译成对应的机器语言,最终由操作系统执行。

JVM解释执行字节码文件就是JVM操作Java解释器进行解释执行字节码文件的过程。

维基百科
机器语言:机器语言(machine language)是一种指令集的体系。这种指令集称为机器代码(machine code),是计算机的CPU可直接解读的数据。

结语

实际上JVM执行字节码文件远比这复杂,其中还包括即时编译器、指令重排等优化。这里只是对Java程序的执行过程做一个大致的介绍,让Java程序员能够明白自己写的程序在JVM里到底是如何执行的。如果要深入研究JVM的更多细节,建议大家去看书或其他资料。

不要再问我Java程序是怎么执行的了!的更多相关文章

  1. 求你了,再问你Java内存模型的时候别再给我讲堆栈方法区了…

    GitHub 4.1k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 4.1k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 4.1k Star 的 ...

  2. 面试官,不要再问我“Java GC垃圾回收机制”了

    Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底层原理,图文并茂,突破学习及面试瓶颈. 楔子-JVM内存结构补充 在上篇<JVM之内存结构详解> ...

  3. 面试官,不要再问我“Java 垃圾收集器”了

    如果Java虚拟机中标记清除算法.标记整理算法.复制算法.分代算法这些属于GC收集算法中的方法论,那么"GC收集器"则是这些方法论的具体实现. 在面试过程中这个深度的问题涉及的比较 ...

  4. 面试官,不要再问我“Java虚拟机类加载机制”了

    关于Java虚拟机类加载机制往往有两方面的面试题:根据程序判断输出结果和讲讲虚拟机类加载机制的流程.其实这两类题本质上都是考察面试者对Java虚拟机类加载机制的了解. 面试题试水 现在有这样一道判断程 ...

  5. 面试官,不要再问我“Java虚拟机类加载机制”了(转载)

    关于Java虚拟机类加载机制往往有两方面的 面试题:根据程序判断输出结果和讲讲虚拟机类加载机制的流程.其实这两类题本质上都是考察面试者对Java虚拟机类加载机制的了解. 面试题试水 现在有这样一道判断 ...

  6. 面试官,不要再问我“Java 垃圾收集器”了(转载)

    如果Java虚拟机中标记清除算法.标记整理算法.复制算法.分代算法这些属于GC收集算法中的方法论,那么"GC收集器"则是这些方法论的具体实现. 在 面试过程中这个深度的问题涉及的比 ...

  7. Java 程序是如何执行的

    Java 程序是如何执行的 了解任何一门语言的精髓都是先俯览其全貌,从宏观的视角把握全局,然后再深入每个知识点逐个击破,这样就可以深入而快速的掌握一项技能.同样学习 Java 也是如此,本节就让我们先 ...

  8. 再问你Java内存模型的时候别再给我讲堆栈方法区

    在介绍Java内存模型之前,先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上做了哪些事情.要说计算机的内存模型,就要说一下一段古老的历史,看一下为什么要有内存模型 ...

  9. 用java程序调用ffmpeg执行视频文件格式转换flv

    用java小例题说明更直观:(可以直接编译运行)环境我在windows平台下测试的...需要在e:/下有ffmpeg.exe;mencoder.exe;drv43260.dll;pncrt.dll共4 ...

随机推荐

  1. win32Helper

    点击别的winform窗口的按钮 #region 点击别的窗口的按钮 [DllImport("user32.dll", EntryPoint = "FindWindowA ...

  2. Python杂谈: 集合中union和update的区别(Python3.x)

    集合中union和update方法都是将多个可迭代的对象合并,但是返回的结果和对初始对象的影响却不一样 # union() 方法 - a.union(b) 将集合a和集合b取并集,并将并集作为一个新的 ...

  3. Resources.resx 未将对象引用设置到对象的实例

    原文:解决使用DevExpress开发错误:未将对象引用设置到对象的实例 在使用DevExpress是总是会出现一些状况.这次同事在他的机器上调试完毕的代码发过来,却出现“未将对象引用设置到对象的实例 ...

  4. MIPS虚拟机代码

    http://download.eeworld.com.cn/download/mamselc/472333http://download.eeworld.com.cn/detail/lamas/36 ...

  5. 获取UWP配置文件中的版本信息

    原文:获取UWP配置文件中的版本信息 在一般的软件中,我们都会显示当前软件的版本信息.以前作者都是在发版的时候修改一下UWP的配置文件中的版本信息和软件中的版本信息.但是每次这样很麻烦,有时间忘记修改 ...

  6. storm和kafka的wordCount

    这个是在window环境下面安装的kafka 下载pom依赖 <dependency> <groupId>org.apache.storm</groupId> &l ...

  7. Android零基础入门第79节:Intent 属性详解(上)

    Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,则取决于Intent的各属性.本期将详细介绍Intent的各属性值,以及 Android如何根据不同属性值来启动相应的组件. ...

  8. 为何只能在其关联的线程内启动timer?(Qt会检查一致性,否则就不执行)

    为何只能在其关联的线程内启动timer? 在QTimer源码分析(以Windows下实现为例) 一文中,我们谈到: QTimer的是通过QObject的timerEvent()实现的,开启和关闭定时器 ...

  9. 星星的模块封装类 IDSStarsScoreView

    1 IDSStarsScoreView 的实现效果     2 类的封装方法:   <声明文件>   // //  IDSStarsScoreView.h //  Near // //  ...

  10. 发布一个Django项目

    一.部署环境准备,准备python3和虚拟环境解释器,virtualenvwrapper 1.修改python3的环境变量 PATH=/opt/python36/bin:/usr/local/sbin ...