JVM系统学习(01):Java代码是怎么运行的

image.png

原文:JVM系统学习(1):Java代码是怎么运行的

引出JRE


Java代码有多种运行方法,我们接触的最多的应该是在Java开发工具中运行,双击Jar运行,以及在命令中运行。当然,这些执行方式都离不开JRE,也就是Java运行时环境

实际上,Jre仅包含了运行java程序的必要组件,包含JVM(java虚拟机)以及核心类库。我们接触最多的JDK(java开发工具包)同样包含了JRE,并且还附带了一系列的开发、诊断工具。

大学的时候接触计算机语言,应该更先接触到C、C++程序,在学习C++的时候,我们都知道在C的世界里不需要 额外的运行时环境,可以直接背编译成CPU所能理解的代码格式,也就是机器码

既然C++的运行方式已经如此成熟了,那为什么Java要在虚拟机里运行?为什么就不能学习C++的这个运行原理,丢弃JVM呢?还有JVM又是如何运行java代码的?它的性能又如何? (真实内心独白:随着程序这条路越走越远,发现遇到的问题也越来越多,尤其是越是那些原本认为是最基础的反而是最难搞明白的,心里开始发慌,这些基础的、原理性的东西搞不明白我又怎么能写出高效、健壮的代码呢。)需要将这些问题一个个的弄清楚。

为什么Java代码要在虚拟机里运行?


Java作为一门高级语言,他的语法非常的复杂,抽象程度也很高。所以直接在硬件上运行这种复杂的程序并不现实。所以,在运行Java程序之前我们需要先对它进行一系列的转换。

这个转换是怎么操作的呢?现在的主流思想是这样子的,设计一个面向Java语言特性的虚拟机,并通过编译器将Java语言转换成虚拟机所能识别的指令序列,也就是Java字节码。(补充:之所以取名java字节码是因为字节码指令的操作码被固定为一个字节)。

举例来说,下图中的中间列,正是Java写的HelloWorld程序编译而成的字节码。我们也可以将反汇编成人类可轻松认识的代码程序。

image.png

我们所熟悉的Java虚拟机是可以由硬件来实现的,也可以有软件来实现。更为常见的是在现有的个OS(windows,mac,linux等)上提供软件实现。这么做的意义是一旦一个java程序被编程成字节码,那么这个字节码便可以在任何一个装有jvm软件的平台上运行(在不同平台的jvm软件中运行)。这也成就了Java语言的:一处编写,到处运行

虚拟机的另外一个好处是,它带来了一个托管环境。这个托管环境可以代替我们处理一些冗长的、而且容易出错的部分。其中最广为人知的便是:自动内容管理 与 垃圾回收。初次之外,这一托管环境还提供了:数组越界、动态类型、安全权限等动态检测,使我们免于书写这些无关业务逻辑的代码。

Java虚拟机是怎样运行java字节码的


下面以标准的Java虚拟机HotSpot虚拟机为例,从虚拟机以及底层硬件两个角度,来看下具体的运行机制。

从虚拟机的角度,执行Java代码首先需要将它编译成字节码文件(.class),然后将字节码文件加载到虚拟机中。加载后的Java类会被存放于方法区(Method Area)中,实际运行时虚拟机会执行方法区中的代码。

如果了解过X86的话,会发现这个跟其中的段式内存管理中的代码端有些相似。而且,JVM同样将内存划分为堆和栈来存储运行时数据。不同的是,JVM会将方法去细分为面向Java方法的Java方法栈以及面向本地方法(用C++写的native方法)的本地方法栈,以及存放各个线程执行位置的PC寄存器。

image.png

在运行过程中,每当调用进入一个Java方法,JVM会在当前线程的Java方法栈中生成一个栈帧,用来存放局部变量以及以及字节码的操作数。这个栈帧的大小是提前计算好的,而且Java虚拟机不要求栈帧在内存中必须连续分布。

当退出当前执行的方法时,JVM不管是正常技术还是异常接触,都会从Java方法栈中弹出当前现成的当前栈帧,将之舍弃。

从硬件角度,java字节码是无法直接执行的。因此,JVM还是需要将字节码翻译成机器码的,这点与C++语言是一样的,因为对于机器还说,他能识别的只有机器码,不认识什么java、c++、Python、SQL……等等,这点其实很好理解,因为想要识别这些那OS必须适配这些语言,有OS翻译成机器码,或者硬件本身就适配,适配一两种倒还好,但是编程语言我们也知道有那么多,而且迭代那么快,硬件就在想:“MD,这么多,我肯定适配不过来的,算了,我还是只人我的机器码,让他们适配我”。

在HotSpot中上述翻译的过程有两种:
第一种是解释执行,即逐条将字节码翻译成机器码并执行。
第二种是即时编译(JIT),即将一个方法中所有的字节码全部翻译成机器码后在同一执行。

image.png

前者的优势在于无需等待编译,而后者的优势值运行速度更快。HotSpot模式采用的是混合模式,综合了解释执行器和即时编译器的有点。它会先解释执行字节码,然后会将其中多次被执行的热点代码,以方法为单位进行即时编译。

Java虚拟机的运行效率究竟是怎样的?


HotSpot采用多种技术来提升启动性能及峰值性能,上面提到的即时编译正式其中最重要的技术之一。

即使编译建立在程序符合二八定律的假设上,即20%的代码占据了80%的计算资源。

对于占据大部分的不常用代码,我们不需要将其编译成机器码,而是采用解释执行的方式运行;另一方面,对于近占据小部分的热点代码,可以将其编译成机器码,以达到理想的运行速度。

为了满足不同用户场景的需求,HotSpot内置了多个即时编译器:C1,C2和Graal。Graal是Java10引入的实验性即使编译器,这里主要看C1、C2即时编译器。

之所以引入多个编译器,是为了在编译时间和生成代码的执行效率之间作取舍。

C1又叫做Client编译器,面向的是对启动性能有要的客户端GUI程序,采取的手短相对简单,因为执行时间较短。

C2又叫做Server编译器,面向的是对峰值性能有要求的服务端程序,采用的优化手段相对复杂,因此编译时间相对较长,但同时生产代码的执行效率较高。

从Java7开始,HotSpot默认采用分层编译的方式:热点方法首先会被C1编译,而后热点方法中的热点会被C2编译。

为了不干扰程序的正常运行,HotSpot的即时编译过程是放在额外的编译线程中进行的。HotSpot会根据CPU的数量设置编译线程的数量,并且按照1:2的比例分配给C1、C2编译器。

在计算资源充足的情况下,字节码的解释执行和即时编译可同时进行。编译完成的机器码会在下次调用该方法是启动,以替换原本的解释执行。

总结


Java程序之所以要在JVM中运行,主要是因为JVM赋能了Java的可移植性。

Java虚拟机将运行时内存区域划分为5个部分:方法区、java堆、java方法栈、本地方法栈、PC寄存器/程序计数器。Java程序编译成.class字节码文件后先要加载到运行时内存区的方法区,方能在JVM运行。

为了提高运行效率,标准HotSpot采用的是一种混合执行的策略(解释执行 + 即时编译)。

HotSpot装载了多个即时编译器,以便在编译时间和生成代码的执行效率之间作取舍。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容