读书笔记JVM探秘之六:编译器的那些事儿

前期编译

java源代码——>JVM字节码(class文件)

大致的编译过程:

解析与填充符号表——>注解处理——>分析与字节码生成

具体就是词法分析、语法分析、构建语法树等过程,此阶段几乎不会对代码做出优化,撑死就是做一些冗余处理,比如 int a = 3 + 1; 改成 int a = 4;等。

值得一说的是解语法糖的过程,java有大量的语法糖,泛型、自动装/拆箱、变长参数、foreach循环等。

有语法糖不一定代表性能的提升,大多时候可能都是为了方便开发人员,极端的说它可以有也可以没有。同时,小心语法糖陷阱,比如自动装箱(不要期待在任何时候都会帮你包装成类)。

后期编译

字节码——>机器码(对应平台的)

可以把此阶段的编译器与C++编译器相比较因为功能类似。

解释器与编译器,前者可以直接运行,解释一句就运行一句,因此效率不高;后者先将运行代码编译成机器码才运行,需要等待编译的时间,但运行快。

C++编译器:静态的,把源代码全部编译成机器码再运行,编译和运行分的很开。

JIT(JVM内置):即时编译器,用到什么就编译什么,编译和运行是交叉的。一般有一个解释器和一个编译器配合执行。

JAVA的代码优化大都集中在JIT里,优化算法之多让人目眩,循环展开、方法内链,常量重叠等等。

PS:一个小小的关注点,局部变量没有访问标志,虽然可以这么写:

final int a = 0;

但这个final是没有意义的,也不是说没有意义,就是说在class文件中没有任何体现,final的意义仅仅在前期编译中被保证。如果反射能修改方法体的话,那这个就有意思了(事实上,反射不能修改方法体=。=)

时间: 2024-11-08 17:26:31

读书笔记JVM探秘之六:编译器的那些事儿的相关文章

读书笔记-JVM

局部变量表(虚拟机栈中的一部分)在编译期完成分配,运行期不会再改变大小: 每个方法对应一个栈帧(存储局部变量表.操作数栈.动态链接.方法出口等),栈帧被存储到虚拟机栈中,每个线程对应一个虚拟机栈,方法结束,栈帧生命周期结束,线程结束,虚拟机栈生命周期结束: 如果线程请求的虚拟机栈深度大于虚拟机所允许的深度,throw StackOverflowerror: 如果动态扩展时请求不到足够内存,throw OutOfMemoryError: 所有的对象实例以及数组都要在堆上分配(不绝对),堆是所有线程

[读书笔记]JVM的垃圾收集算法

1.标记-清除算法 (1)算法思想:第一步,标记好所有需要回收的对象:第二步,清除被标记的对象. (2)缺点:时间上,效率不高,无论是标记还是清除操作:空间上,会产生大量不连续的内存碎片,使得占用大内存的对象找不到足够的连续内存而进一步又提前触发一次GC. 标记-清除算法执行过程如下图所示: 2.复制算法 (1)算法思想:内存区分成两部分大小相等的区域.一半作为使用区,一半作为保留区.申请内存时,在使用区进行.GC时,我们将使用区的将被存活的对象复制到保留区,然后将使用区清空,这时我们将原使用区

C++ Primer 5 读书笔记 推荐序 像编译器一样来思考和理解C++语言

像编译器一样来思考和理解C++语言. C++标准库本身就是C++语法的最佳样例. 遵循 google C++ style guide 孟岩 推荐 CPPP 5  C++标准程序库 effective C++ C++ concurrency in action linux多线程服务端编程

<<深入分析javaWeb技术内幕>>读书笔记-JVM内存管理2

JVM垃圾回收策略 1.静态内存分配和回收 编译时已经确定了内存空间大小,程序被加载后则一次性分配好内存空间.程序结束后,则对应栈帧撤销,分配的静态内存空间则被回收. 2.动态内存分配和回收 程序运行动态分配内存空间,回收时则由垃圾收集器负责. 3.垃圾收集器 A.正确的检测出垃圾对象(关键功能) B.释放垃圾对象占用的内存空间 4.基于分代的垃圾收集算法(hostpot) 算法设计思路: 把对象按照寿命的长短进行分组(年轻代,年老代),新创建的对象分配在年轻代中,对象经过几次垃圾回收后,仍然存

java内存区域——深入理解JVM读书笔记

本内容由<深入理解java虚拟机>的部分读书笔记整理而成,本读者计划连载. 通过如下图和文字介绍来了解几个运行时数据区的概念. 方法区:它是各个线程共享的区域,用于内存已被VM加载的类信息.常量.静态变量.即时编译器编译的代码等数据.JVM规范对这个区域的限制很宽松,如同堆一样不需要连续的内存.可选择固定大小.可扩展的大小外,还可以选择不实现垃圾收集.因为在些区域的垃圾收集必要性不高且效果较差.如果回收也是常量池的回收和类型的卸载,但此操作异常困难.当方法区无法满足内存的分配时,抛OutOfM

《C#图解教程》读书笔记之六:接口和转换

本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.接口那点事儿 (1)什么是接口? 一组函数成员而未实现的引用类型.只有类和结构能实现接口. (2)从IComparable接口看接口实例: 假设有如下一段代码,它使用Array类的一个静态方法Sort对一个未排序的int类型数组进行排序,并输出排序后的结果. using System; class Program { static void Main() { var myInt = new[] { 20, 4, 1

《大型网站技术架构》读书笔记之六:永无止境之网站的伸缩性架构

此篇已收录至<大型网站技术架构>读书笔记系列目录贴,点击访问该目录可获取更多内容. 首先,所谓网站的伸缩性,指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力.在整个互联网行业的发展渐进演化中,最重要的技术就是服务器集群,通过不断地向集群中添加服务器来增强整个集群的处理能力. 一.网站架构的伸缩性设计 1.1 不同功能进行物理分离实现伸缩 (1)纵向分离:将业务处理流程上得不同部分分离部署,实现系统的伸缩性: (2)横向分离:将不同的业务模块分离部署

深入JVM读书笔记(一)——jvm数据区基础知识

最近得空,就把<深入理解Java虚拟机>重新看了一遍,特写下现在的读书笔记,总结知识点,记录现在的理解,便于以后的回顾.下面的内容也会按照这本书的章节来划分知识点! Let's go! 想要了解Java虚拟机,一定要先明白Java运行时划分为哪些数据区域,具体的可以参考下图,按照是否为线程私有可以划分为: 线程私有:虚拟机栈.本地方法栈.程序计数器 线程共有:方法区.堆   下面详细说一下各个数据区的作用: 1. 程序计数器(Program Counter Register) 程序计数器是一块

think in java 读书笔记

java中没有单独函数的概念,依赖类的方法. java中优化了向前引用,类可以在调用者之后. java中包的命名方法实际上是网址的倒转. c++中因为存在全局变量和函数所以会存在一个变量名冲突的问题,但是java中不存在全局变量,不同程序设计者通过不同的类将相同名字的变量和方法隔离. static关键字 通常,我们创建类时会指出那个类的对象的外观与行为.除非用new 创建那个类的一个对象,否则实际上并 未得到任何东西.只有执行了new 后,才会正式生成数据存储空间,并可使用相应的方法. 但在两种