0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

由浅入深的了解Java虚拟机

我快闭嘴 来源:集贤网 作者:Linkey bpm 2020-01-01 17:50 次阅读

说到Java虚拟机,相信作为Java程序员的小伙伴们都不陌生,他们每天都在写Java代码,写的代码都是在一个叫做Java虚拟机的东西上执行的。但是如果要问什么是虚拟机,恐怕很多人就会模棱两可了。

我们都知道java程序必须在虚拟机上运行。那么虚拟机到底是什么呢?先看网上搜索到的比较靠谱的解释:

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

这种解释应该算是正确的,但是只描述了虚拟机的外部行为和功能,并没有针对内部原理做出说明。一般情况下我们不需要知道虚拟机的运行原理,只要专注写java代码就可以了,这也正是虚拟机之所以存在的原因--屏蔽底层操作系统平台的不同并且减少基于原生语言开发的复杂性,使java这门语言能够跨各种平台(只要虚拟机厂商在特定平台上实现了虚拟机),并且简单易用。这些都是虚拟机的外部特性,但是从这些信息来解释虚拟机,未免太笼统了,无法让我们知道内部原理。

从进程的角度解释JVM

让我们尝试从操作系统的层面来理解虚拟机。我们知道,虚拟机是运行在操作系统之中的,那么什么东西才能在操作系统中运行呢?当然是进程,因为进程是操作系统中的执行单位。可以这样理解,当它在运行的时候,它就是一个操作系统中的进程实例,当它没有在运行时(作为可执行文件存放于文件系统中),可以把它叫做程序。

对命令行比较熟悉的同学,都知道其实一个命令对应一个可执行的二进制文件,当敲下这个命令并且回车后,就会创建一个进程,加载对应的可执行文件到进程的地址空间中,并且执行其中的指令。下面对比C语言和Java语言的HelloWorld程序来说明问题。

由浅入深的了解Java虚拟机

首先编写C语言版的HelloWorld程序。

编译C语言版的HelloWorld程序:gcc HelloWorld.c-o HelloWorld

运行C语言版的HelloWorld程序:

zhangjg linux:/deve/workspace/HelloWorld/src$./HelloWorld

hello world

gcc编译器编译后的文件直接就是可被操作系统识别的二进制可执行文件,当我们在命令行中敲下。/HelloWorld这条命令的时候,直接创建一个进程,并且将可执行文件加载到进程的地址空间中,执行文件中的指令。

作为对比,我们看一下Java版HelloWord程序的编译和执行形式。

首先编写源文件HelloWord.java :

由浅入深的了解Java虚拟机

编译Java版的HelloWorld程序:

zhangjg linux:/deve/workspace/HelloJava/src$javac HelloWorld.java

zhangjg linux:/deve/workspace/HelloJava/src$ls

HelloWorld.class HelloWorld.java

运行Java版的HelloWorld程序:

zhangjg linux:/deve/workspace/HelloJava/src$java-classpath.HelloWorld

HelloWorld

从上面的过程可以看到,在运行Java版的HelloWorld程序的时候,敲入的命令并不是。/HelloWorld.class。因为class文件并不是可以直接被操作系统识别的二进制可执行文件。我们敲入的是java这个命令。这个命令说明,我们首先启动的是一个叫做java的程序,这个java程序在运行起来之后就是一个JVM进程实例。

上面的命令执行流程是这样的:

java命令首先启动虚拟机进程,虚拟机进程成功启动后,读取参数“HelloWorld”,把他作为初始类加载到内存,对这个类进行初始化和动态链接(关于类的初始化和动态链接会在后面的博客中介绍),然后从这个类的main方法开始执行。也就是说我们的.class文件不是直接被系统加载后直接在cpu上执行的,而是被一个叫做虚拟机的进程托管的。首先必须虚拟机进程启动就绪,然后由虚拟机中的类加载器加载必要的class文件,包括jdk中的基础类(如String和Object等),然后由虚拟机进程解释class字节码指令,把这些字节码指令翻译成本机cpu能够识别的指令,才能在cpu上运行。

从这个层面上来看,在执行一个所谓的java程序的时候,真真正正在执行的是一个叫做Java虚拟机的进程,而不是我们写的一个个的class文件。这个叫做虚拟机的进程处理一些底层的操作,比如内存的分配和释放等等。我们编写的class文件只是虚拟机进程执行时需要的“原料”。这些“原料”在运行时被加载到虚拟机中,被虚拟机解释执行,以控制虚拟机实现我们java代码中所定义的一些相对高层的操作,比如创建一个文件等,可以将class文件中的信息看做对虚拟机的控制信息,也就是一种虚拟指令。

编程语言也有自己的原理,学习一门语言,主要是把它的原理搞明白。看似一个简单的HelloWorld程序,也有很多深入的内容值得剖析。

JVM体系结构简介

为了展示虚拟机进程和class文件的关系,特意画了下面一张图:

根据上图表达的内容,编译之后的class文件是作为Java虚拟机的原料被输入到Java虚拟机的内部的,那么具体由谁来做这一部分工作呢?其实在Java虚拟机内部,有一个叫做类加载器的子系统,这个子系统用来在运行时根据需要加载类。注意上面一句话中的“根据需要”四个字。在Java虚拟机执行过程中,只有他需要一个类的时候,才会调用类加载器来加载这个类,并不会在开始运行时加载所有的类。就像一个人,只有饿的时候才去吃饭,而不是一次把一年的饭都吃到肚子里。一般来说,虚拟机加载类的时机,在第一次使用一个新的类的时候。本专栏后面的文章会具体讨论Java中的类加载器。

由虚拟机加载的类,被加载到Java虚拟机内存中之后,虚拟机会读取并执行它里面存在的字节码指令。虚拟机中执行字节码指令的部分叫做执行引擎。就像一个人,不是把饭吃下去就完事了,还要进行消化,执行引擎就相当于人的肠胃系统。在执行的过程中还会把各个class文件动态的连接起来。关于执行引擎的具体行为和动态链接相关的内容也会在本专栏后续的文章中进行讨论。

我们知道,Java虚拟机会进行自动内存管理。具体说来就是自动释放没有用的对象,而不需要程序员编写代码来释放分配的内存。这部分工作由垃圾收集子系统负责。

从上面的论述可以知道,一个Java虚拟机实例在运行过程中有三个子系统来保障它的正常运行,分别是类加载器子系统,执行引擎子系统和垃圾收集子系统。如下图所示:

虚拟机的运行,必须加载class文件,并且执行class文件中的字节码指令。它做这么多事情,必须需要自己的空间。就像人吃下去的东西首先要放在胃中。虚拟机也需要空间来存放个中数据。首先,加载的字节码,需要一个单独的内存空间来存放;一个线程的执行,也需要内存空间来维护方法的调用关系,存放方法中的数据和中间计算结果;在执行的过程中,无法避免的要创建对象,创建的对象需要一个专门的内存空间来存放。

总结:

1虚拟机并不神秘,在操作系统的角度看来,它只是一个普通进程。

2这个叫做虚拟机的进程比较特殊,它能够加载我们编写的class文件。如果把JVM比作一个人,那么class文件就是我们吃的食物。

3加载class文件的是一个叫做类加载器的子系统。就好比我们的嘴巴,把食物吃到肚子里。

4虚拟机中的执行引擎用来执行class文件中的字节码指令。就好比我们的肠胃,对吃进去的食物进行消化。

5虚拟机在执行过程中,要分配内存创建对象。当这些对象过时无用了,必须要自动清理这些无用的对象。清理对象回收内存的任务由垃圾收集器负责。就好比人吃进去的食物,在消化之后,必须把废物排出体外,腾出空间可以在下次饿的时候吃饭并消化食物。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 计算机
    +关注

    关注

    19

    文章

    6631

    浏览量

    84368
  • JAVA
    +关注

    关注

    19

    文章

    2903

    浏览量

    102977
  • 源代码
    +关注

    关注

    94

    文章

    2923

    浏览量

    66047
  • 虚拟机
    +关注

    关注

    1

    文章

    852

    浏览量

    27345
收藏 人收藏

    评论

    相关推荐

    JAVA虚拟机环境如何在IMX6平台上搭建?

    JAVA游戏,更是普及。嵌入式硬件平台种类众多,操作系统也各不相同,不同的用户和公司有自己不同的计算机环境偏好,而软件为了能在这些不同的环境里正常运行,就需要独立于这些平台。而JAVA虚拟机是实现这一特点
    发表于 01-15 12:02

    请问QTE可以同几种JAVA虚拟机集成

    《嵌入式linux应用开发完全手册》第500页中有讲:“QTE可以同几种JAVA虚拟机集成。JAVA程序可以基于QTE的工作平台上运行,提供同源程序相同的效果”我就是想请问,是否有那个版本的QTE是有带
    发表于 05-24 05:45

    嵌入式Java虚拟机的性能优化技术

    作者:孙京毅无线手持设备市场对Java产生了巨大的需求增长,目前每10台新出手机中就有8台支持Java。本文关注嵌入式设备Java平台的性能问题,详细介绍振戎融通自主研发的Java
    发表于 07-18 06:26

    嵌入式Java虚拟机优化技术总结的太棒了

    嵌入式Java虚拟机优化技术总结的太棒了
    发表于 04-25 06:47

    浅谈Java虚拟机的研究与移植

    Kaffe移植的关键技术及方案基于ST20嵌入式系统的Java虚拟机研究与移植
    发表于 04-25 09:49

    Java虚拟机介绍

    什么是JVM?Java虚拟机Java Virtual Machine, JVM)实际上是一个类似于真实计算机系统的抽象机(Abstract Computing Machine),它拥有一组指令集,用来解释“.class”字节代
    发表于 04-10 16:15 0次下载

    Java虚拟机向ARM平台的移植

    介绍Java 虚拟机的概念,以常用的KVM 为例,讲述了将Java 虚拟机移植到ARM 平台的方法,重点介绍了移植过程中的编译选项。
    发表于 09-23 11:54 38次下载

    Java虚拟机向ARM平台的移植

    介绍Java 虚拟机的概念,以常用的KVM 为例,讲述了将Java 虚拟机移植到ARM 平台的方法,重点介绍了移植过程中的编译选项。
    发表于 09-23 11:54 22次下载

    微软java虚拟机下载

    微软java虚拟机下载:Java虚拟机(JVM)是Java Virtual Machine的缩写,它是一个虚构出来的计算机,是通过在实际的计
    发表于 02-26 08:26 38次下载

    Java虚拟机基础

    JVM基础----java虚拟机的学习内容。
    发表于 10-30 10:21 0次下载

    深入JAVA虚拟机

    深入JAVA虚拟机
    发表于 03-19 11:24 1次下载

    JAVA虚拟机的体系结构及基本类型

    JAVA虚拟机的体系结构 下图是JAVA虚拟机的结构图,每个Java虚拟机都有一个类装载子系统,
    发表于 09-27 11:30 0次下载
    <b class='flag-5'>JAVA</b><b class='flag-5'>虚拟机</b>的体系结构及基本类型

    Java虚拟机参数调优

    随着JAVA在应用系统级的项目开发中的使用越来越广泛,虚拟机、垃圾收集、热点编译、J2EE等新技术层出不穷,JAVA作为系统级开发的一个选择的优势也越来越明显,在此同时其不能完全编译、垃圾收集
    发表于 04-03 11:29 1次下载

    Java入手如何了解虚拟机(VM)

    虚拟机的设计架构有两种: 基于求值栈、基于寄存器,如果从更大的范围可以认为只要实现了功能的都可以认为是虚拟机,通过直接遍历AST得到结果的也可以算一种虚拟机
    的头像 发表于 03-03 10:00 570次阅读
    从<b class='flag-5'>Java</b>入手如何<b class='flag-5'>了解</b><b class='flag-5'>虚拟机</b>(VM)

    深入浅出地介绍Java虚拟机的相关知识

    Java 虚拟机Java Virtual Machine,简称 JVM)是 Java 语言最核心的技术之一,也是 Java 开发者必须掌握
    的头像 发表于 06-06 14:49 2662次阅读