【深入理解JAVA虚拟机】第4部分.程序编译与代码优化.1.编译期优化。这章编译和实战部分没理解通,以后再看。
1、概述
1.1、编译器的分类
前端编译器:Sun的Javac、 Eclipse JDT中的增量式编译器(ECJ)[1]。 把*.java文件转变成*.class文件
JIT编译器:HotSpot VM的C1、 C2编译器。是指虚拟机的后端运行期编译器 ,把字节码转变成机器码
AOT编译器:GNU Compiler for the Java(GCJ)[2]、 Excelsior JET[3] 。静态提前编译器 ,直接把*.java文件编译成本地机器代码
1.2、编译期优化的方向
虚拟机设计团队把对性能的优化集中到了后端的即时编译器中,这样可以让那些不是由Javac产生的Class文件(如JRuby、 Groovy等语言的Class文件)也同样能享受到编译器优化所带来的好处。
但是Javac做了许多针对Java语言编码过程的优化措施来改善程序员的编码风格和提高编码效率。
相当多新生的Java语法特性,都是靠编译器的“语法糖”来实现,而不是依赖虚拟机的底层改进来支持,
可以说,Java中即时编译器在运行期的优化过程对于程序运行来说更重要,而前端编译器在编译期的优化过程对于程序编码来说关系更加密切。
所以,本章后面主要是介绍编译器执行过程和语法糖。
2、Javac编译器
javac本身就是一个由Java语言编写的程序 ,源码存放在JDK_SRC_HOME/langtools/src/share/classes/com/sun/tools/javac
从SunJavac的代码来看,编译过程大致可以分为3个过程,分别是:
解析与填充符号表过程。
插入式注解处理器的注解处理过程。
分析与字节码生成过程。
这3个步骤之间的关系与交互顺序如图10-4所示。

Javac编译动作的入口是com.sun.tools.javac.main.JavaCompiler类,上述3个过程的代码逻辑集中在这个类的compile()和compile2()方法中 。代码详略。
2.1、解析与填充符号表
1.词法、 语法分析
词法分析是将源代码的字符流转变为标记(Token)集合,单个字符是程序编写过程的最小元素,而标记则是编译过程的最小元素 。
在Javac的源码中,语法分析过程由com.sun.tools.javac.parser.Parser类实现,这个阶段产出的抽象语法树由com.sun.tools.javac.tree.JCTree类表示,
经过这个步骤之后,编译器就基本不会再对源码文件进行操作了,后续的操作都建立在抽象语法树之上。
2.填充符号表
填充符号表的过程由com.sun.tools.javac.comp.Enter类实现
2.3 注解处理器
2.4 语义分析与字节码生成
1.标注检查
2.数据及控制流分析
3.解语法糖
4.字节码生成
3、Java语法糖的味道
3.1 泛型与类型擦除
Java的泛型在编译时是把泛型替换了的,专业名字叫“泛型擦除”,所以在编译后是指向同一种类型的,也就是说ArrayList<int>与ArrayList<String> 是同一个类。
所以,对泛型重载,是不可以的。
void fun(ArrayList<int>)
void fun(ArrayList<String>)
这是会报错的。
但,如果两个函数的返回值不同,又不可以执行,这是java在一定程度上的妥协,但结果却未被了重载本身的要素,不能通过返回值去指派一个方法调用。
所以,java的泛型设计是被很多人吐槽的。
3.2 自动装箱、 拆箱与遍历循环
自动装箱是自动加了 Integer.valueOf()之类的方法
循环遍历是自动添加了迭代器。
3.3 条件编译
在C/C++中有#if来控制是否参与编译,但在java里为何没有?
原因是不需要。
因为Java语言天然的编译方式(编译器并非一个个地编译Java文件,而是将所有编译单元的语法树顶级节点输入到待处理列表后再进行编译,因此各个文件之间能够互相提供符号信息)无须使用预处理器。
虽然不需要,但java里也可以模拟条件编译,编译器在一些特定条件下可以把一些分支给优化掉,条件就是if(true)的else分支。
4 实战:插入式注解处理器
未懂。
【深入理解JAVA虚拟机】第4部分.程序编译与代码优化.1.编译期优化。这章编译和实战部分没理解通,以后再看。的更多相关文章
- 深入理解Java虚拟机(第三版)-14. 线程安全与锁优化
14. 线程安全与锁优化 1. 什么是线程安全? 当多个线程同时访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替进行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个 ...
- 深入理解Java虚拟机--下
深入理解Java虚拟机--下 参考:https://www.zybuluo.com/jewes/note/57352 第10章 早期(编译期)优化 10.1 概述 Java语言的"编译期&q ...
- 深入理解Java虚拟机之自己编译JDK
题外话 最近在阅读<深入理解Java虚拟机>,其中有一小节实战是自己编译JDK,实际操作下来后遇到问题不少,为此特地记录,也希望可以给大家带来一些参考! 前置准备 平台及工具:Window ...
- 深入理解Java虚拟机(程序编译与代码优化)
文章首发于微信公众号:BaronTalk,欢迎关注! 对于性能和效率的追求一直是程序开发中永恒不变的宗旨,除了我们自己在编码过程中要充分考虑代码的性能和效率,虚拟机在编译阶段也会对代码进行优化.本文就 ...
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- 《深入理解 java虚拟机》学习笔记
java内存区域详解 以下内容参考自<深入理解 java虚拟机 JVM高级特性与最佳实践>,其中图片大多取自网络与本书,以供学习和参考.
- 理解Java虚拟机体系结构
1 概述 众所周知,Java支持平台无关性.安全性和网络移动性.而Java平台由Java虚拟机和Java核心类所构成,它为纯Java程序提供了统一的编程接口,而不管下层操作系统是什么.正是得益于Jav ...
- (1) 深入理解Java虚拟机到底是什么?
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 作为一个Java程序员,我们每天都在写Java ...
- 深入理解java虚拟机(6)---内存模型与线程 & Volatile
其实关于线程的使用,之前已经写过博客讲解过这部分的内容: http://www.cnblogs.com/deman/category/621531.html JVM里面关于多线程的部分,主要是多线程是 ...
随机推荐
- 微服务~Consul服务注册与发现
服务发现是基于微服务架构的关键原则之一.尝试配置每个客户端或某种形式的约定可能非常困难,可以非常脆弱.Consul通过HTTP API和DNS提供服务发现服务.Spring Cloud Consul利 ...
- xamarin for android webservice
首先新建一个空网站,添加一个webservice服务.然后在UserWebService.cs类里编写对外服务的方法 [WebMethod] public string IsCorret(string ...
- unity收集log工具
参考 yusong:http://www.xuanyusong.com/archives/2477 凉鞋 :https://www.cnblogs.com/liangxiegame/p/Uni ...
- 封装你的协程Unity TaskManager
unity5提供了协程,不过用起来很蛋疼,当然如果是unity2017 你就可以用async await了 提供一个TaskManager来封装协程(github https://github.co ...
- [转]oracle update set select from 关联更新
本文转自:http://blog.csdn.net/disiwei1012/article/details/52589181 http://www.blogjava.net/Jhonney/archi ...
- 解决 Java 调用 Azure SDK 证书错误 javax.net.ssl.SSLHandshakeException
Azure 作为微软的公有云平台,提供了非常丰富的 SDK 和 API 让开发人员可以非常方便的调用的各项服务,目前除了自家的 .NET.Java.Python. nodeJS.Ruby,PHP 等语 ...
- centos 同步网络时间
centos 同步网络时间 # yum -y install ntp ntpdate # ntpdate cn.pool.ntp.org # date
- .netcore2.0 发布CentOS7
1.一般在windows pc上使用vscode 开发好.netcore 程序如果需要发布到其他平台需要注意一些事情 首先需要明白2个概念:FDD(Framework-dependent deploy ...
- mysql client does not support authentication
打开mysql 命令行 mysql> alter user 'root'@'localhost' identified with mysql_native_password by '123456 ...
- AngularJS 指令 实现文本水平滚动效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...