java语言 编译原理_【Java学习】深入分析Java的编译原理

在《Java代码的编译与反编译》中,有过关于Java语言的编译和反编译的介绍。我们可以通过javac命令将Java程序的源代码编译成Java字节码,即我们常说的class文件。这是我们通常意义上理解的编译。

但是,字节码并不是机器语言,要想让机器能够执行,还需要把字节码翻译成机器指令。这个过程是Java虚拟机做的,这个过程也叫编译。是更深层次的编译。

在编译原理中,把源代码翻译成机器指令,一般要经过以下几个重要步骤:

bf8e430558034495a4c76a090f46b23e.png

根据完成任务不同,可以将编译器的组成部分划分为前端(Front End)与后端(Back End)。

前端编译主要指与源语言有关但与目标机无关的部分,包括词法分析、语法分析、语义分析与中间代码生成。

后端编译主要指与目标机有关的部分,包括代码优化和目标代码生成等。

我们可以把将.java文件编译成.class的编译过程称之为前端编译。把将.class文件翻译成机器指令的编译过程称之为后端编译。

Java中的前端编译

前端编译主要指与源语言有关但与目标机无关的部分,包括词法分析、语法分析、语义分析与中间代码生成。

我们所熟知的javac的编译就是前端编译。除了这种以外,我们使用的很多IDE,如eclipse,idea等,都内置了前端编译器。主要功能就是把.java代码转换成.class代码。

词法分析

词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,将字符序列转换为标记(token)序列的过程。这里的标记是一个字符串,是构成源代码的最小单位。在这个过程中,词法分析器还会对标记进行分类。

词法分析器通常不会关心标记之间的关系(属于语法分析的范畴),举例来说:词法分析器能够将括号识别为标记,但并不保证括号是否匹配。

语法分析

语法分析的任务是在词法分析的基础上将单词序列组合成各类语法短语,如“程序”,“语句”,“表达式”等等.语法分析程序判断源程序在结构上是否正确.源程序的结构由上下文无关文法描述。

语义分析

语义分析是编译过程的一个逻辑阶段, 语义分析的任务是对结构上正确的源程序进行上下文有关性质的审查,进行类型审查。语义分析是审查源程序有无语义错误,为代码生成阶段收集类型信息。

语义分析的一个重要部分就是类型检查。比如很多语言要求数组下标必须为整数,如果使用浮点数作为下标,编译器就必须报错。再比如,很多语言允许某些类型转换,称为自动类型转换。

中间代码生成

在源程序的语法分析和语义分析完成之后,很多编译器生成一个明确的低级的或类机器语言的中间表示。该中间表示有两个重要的性质: 1.易于生成; 2.能够轻松地翻译为目标机器上的语言。

在Java中,javac执行的结果就是得到一个字节码,而这个字节码其实就是一种中间代码。

PS:著名的解语法糖操作,也是在javac中完成的。

Java中的后端编译

首先,我们大家都知道,通常通过 javac 将程序源代码编译,转换成 java 字节码,JVM 通过解释字节码将其翻译成对应的机器指令,逐条读入,逐条解释翻译。很显然,经过解释执行,其执行速度必然会比可执行的二进制字节码程序慢很多。这就是传统的JVM的解释器(Interpreter)的功能。为了解决这种效率问题,引入了 JIT 技术。

JAVA程序还是通过解释器进行解释执行,当JVM发现某个方法或代码块运行特别频繁的时候,就会认为这是“热点代码”(Hot Spot Code)。然后JIT会把部分“热点代码”翻译成本地机器相关的机器码,并进行优化,然后再把翻译后的机器码缓存起来,以备下次使用。

HotSpot虚拟机中内置了两个JIT编译器:Client Complier和Server Complier,分别用在客户端和服务端,目前主流的HotSpot虚拟机中默认是采用解释器与其中一个编译器直接配合的方式工作。

当 JVM 执行代码时,它并不立即开始编译代码。首先,如果这段代码本身在将来只会被执行一次,那么从本质上看,编译就是在浪费精力。因为将代码翻译成 java 字节码相对于编译这段代码并执行代码来说,要快很多。第二个原因是最优化,当 JVM 执行某一方法或遍历循环的次数越多,就会更加了解代码结构,那么 JVM 在编译代码的时候就做出相应的优化。

在机器上,执行java -version命令就可以看到自己安装的JDK中JIT是哪种模式:

1847de2a62cd7147a1d608810dd5c92a.png

上图是我的机器上安装的jdk1.8,可以看到,他是Server Compile,但是,需要说明的是,无论是Client Complier还是Server Complier,解释器与编译器的搭配使用方式都是混合模式,即上图中的mixed mode。

热点检测

上面我们说过,要想触发JIT,首先需要识别出热点代码。目前主要的热点代码识别方式是热点探测(Hot Spot Detection),有以下两种:

1、基于采样的方式探测(Sample Based Hot Spot Detection) :周期性检测各个线程的栈顶,发现某个方法经常出险在栈顶,就认为是热点方法。好处就是简单,缺点就是无法精确确认一个方法的热度。容易受线程阻塞或别的原因干扰热点探测。

2、基于计数器的热点探测(Counter Based Hot Spot Detection)。采用这种方法的虚拟机会为每个方法,甚至是代码块建立计数器,统计方法的执行次数,某个方法超过阀值就认为是热点方法,触发JIT编译。

在HotSpot虚拟机中使用的是第二种——基于计数器的热点探测方法,因此它为每个方法准备了两个计数器:方法调用计数器和回边计数器。

方法计数器。顾名思义,就是记录一个方法被调用次数的计数器。

回边计数器。是记录方法中的for或者while的运行次数的计数器。

编译优化

前面提到过,JIT除了具有缓存的功能外,还会对代码做各种优化。说到这里,不得不佩服HotSpot的开发者,他们在JIT中对于代码优化真的算是面面俱到了。

这里简答提及几个我觉得比较重要的优化技术,并不准备直接展开,读者感兴趣的话,我后面再写文章单独介绍。

逃逸分析、 锁消除、 锁膨胀、 方法内联、 空值检查消除、 类型检测消除、 公共子表达式消除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/460214.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaSE_base04_集合框架

四、集合框架1:String类:字符串(重点) (1)多个字符组成的一个序列,叫字符串。 生活中很多数据的描述都采用的是字符串的。而且我们还会对其进行操作。 所以,java就提供了这样的一个类供我们使用。 (2)创建字…

火狐浏览器中打开java_将Firefox浏览器嵌入Java Swing中

小编典典这是一些示例代码import java.awt.Color;import java.awt.Component;import java.awt.Container;import java.awt.FlowLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.FileNotFoundException;import java.io.File;imp…

实验 使用 vivado zedboard GPIO 开关 开控制 LED

前面我做了几个实验 都没有用过 开关,这一次用一用 发现 vivado 真的挺方便 所以 使用 vivado 开发 1.建工程 我使用 vivado 2013.4 创建新工程 –》 next –》next 勾选 Do not specify sources at this time //这样跳过后面两个添加文件页面 选择 board –》 ze…

java 最优化_java-多维度求最优解

拿出11条数据//条件每个位置(position)的人数限制每队(team)人数不能超过7人credits的总和在100分之内(包含100)总分(points)最高//位置人数限制position-1 : 1 position-2 : 3-5 position-3 : 1-3 position-4 : 3-5//模拟数据{points credits position team56 9.0 1 t154 9.1 …

polymer web componets 大前端

大前端 东南水乡 一叶小舟拂过水面 船上两位大侠把酒言欢 一位是玉真人 另一位是张真人 两人喝到开心处 变作对联起来 上联 前端研究,研究个屁~ 下联 前端设计,设计个屁~ 横批 前端sb特色 polymer 提供创建自定义和标准dom元素类似的自定义元素功能 可以…

citespace安装如何配置JAVA_citespace超详细安装教程

想用citespace写篇量化的文献综述但是试了很多次一直运行不了,无奈因为要分析的论文太多,只能继续学着下载……在踩了很多坑之后终于搞定了!!我参考了知乎大神们写的学习指南,但在下载过程中还是会遇到一点点小问题&am…

Ubuntu下安装配置JDK

第一步:下载jdk-7-linux-i586.tar.gz wget -c http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-i586.tar.gz 若失败,则自行下载即可。 第二步:解压安装 sudo tar zxvf ./jdk-7-linux-i586.tar.gz -C /usr/lib/jvm cd /usr/lib/…

必应(Bing)每日图片获取API

必应(Bing)每日图片获取API January 11, 2015 API http://lab.dobyi.com/api/bing.php 介绍 ValueDescriptiontitle标题desc描述url图片地址你们自由发挥……

java取模多位数_JAVA大数类—基础操作(加减乘除、取模、四舍五入、设置保留位数)...

当基础数据类型长度无法满足需求时可以使用大数类构造方法接受字符串为参数1 BigInteger bInt new BigInteger("123123");2 BigDecimal bDouble new BigDecimal("123123.123123124");基础操作(取模使用divideAndRemainder方法,返回的数组第二…

HDU 4902

数据太弱&#xff0c;直接让我小暴力一下就过了&#xff0c;一开始没注意到时间是15000MS&#xff0c;队友发现真是太给力了 #include <cstdio> #include <cstring> int n,q,a[100005],x[100005],p,l[100005],r[100005],t[100005]; int tree[1000005]; void build(…

tcp/udp高并发和高吐吞性能测试工具

在编写一个网络服务的时候都比较关心这个服务能达到多少并发连接,而在这连接的基础上又能达到一个怎样的交互能力.编写服务已经是一件很花力气的事情,而还要去编写一个能够体现结果的测试工具就更加消耗工作时间.下面介绍一个测试工具只需要简单地设置一下就能对tcp/udp服务进行…

java socket 对方关闭_java Socket判断对方是否已关闭连接

如何判断远端socket是否已经断开连接&#xff0c;如果断开那么需要重新连接。1通过socket类的方法isClosed()、isConnected()、isInputStreamShutdown()、isOutputStreamShutdown()等&#xff0c;这些方法都是本地端的状态&#xff0c;无法判断远端是否已经断开连接。2通过Outp…

几个数字的和

ctrl z 的使用 #include<iostream> using namespace std;main() {int num,sum0;while(cin>>num) {sumnum;}cout<<"和为"<<sum<<endl; } View Code#include<iostream> using namespace std; main() { int num,s…

sharepoint 2013基于AD的Form表单登录(三)——选择用户时,屏蔽掉AD。

//来源&#xff1a;http://www.cnblogs.com/lrforever/p/3695820.html 隐藏AD人员选择&#xff0c;$ad.IsVisible设置为true&#xff0c;则显示出AD里用户$cpm Get-SPClaimProviderManager $ad get-spclaimprovider -identity "AD" $ad.IsVisible $false $cpm.Up…

java synchronized boolean_java中synchronized关键字

代码示例&#xff1a;package com.test;/** x,y值为什么不能保持相同&#xff1b;**/public class Pair implements Runnable{boolean b false;private int x;private int y;public Pair(int x,int y){this.x x;this.y y;}public Pair(){}public void incrementX(){x;}publi…

网站在线压力测试工具Load Impact

关于Load ImpactLoad Impact是一个一个在线的网站压力测试服务及工具&#xff0c;模拟多用户同时访问你的站点&#xff0c;并出具报告以分析你的站点可以支撑的访问者数量&#xff0c;它能让你通过简单的几次点击就能测试出你的网站的性能。不过免费用户只能同时并发50个虚拟访…

Loading 遮蔽层 简单实现。

<!--背景div--><div id"bg" class"bg" style"display:none;text-align: center;"></div> <!--loading 图片 div --><div class"mydiv" id"popDiv"><img src"${root }/common/images/…

java服务器向客户端发消息_java一个简单的客户端向服务端发送消息

java一个简单的客户端向服务端发送消息客户端代码&#xff1a;package com.chenghu.tcpip;import java.io.IOException;import java.io.OutputStream;import java.net.InetAddress;import java.net.Socket;//客户端public class TcpClientDemo01 {public static void main(Stri…

sc.next在java什么意思_sc.next() 和 nextLine 的原理

对java的Scanner类的next开头的相关类有点纠结&#xff0c;看了一些博客大致懂了&#xff0c;整理下代码事例直接参考了这位大佬的https://blog.csdn.net/long71751380/article/details/94008351. 总的原理以一段代码为例,scanner类import java.util.Scanner;public class Next…

WPF RichTextBox相关总结

由于公司涉及到聊天对话框的功能&#xff0c;就想到了RichTextBox&#xff0c;查阅相关资料&#xff0c;总结下&#xff1a; 一、RichTextBox的内容相关的类 1.1RichTextBox的内容结构 RichTexBox是个可编辑控件&#xff0c;可编辑我们很容易想到word的可编辑&#xff0c;在wor…