JVM 切入点-Hellow word 会当凌绝顶、一览众山小 前端编译与优化

JVM读书总结

切入点-Hellow word

学习中知识点很多逐个记概念很容易忘记,要找到切入点通过这个切入点生根,然后形成知识树或叫知识体系,在从知识体系上延伸出很多的知识点,前后依赖。这样就很容及记住某个知识点的来龙去脉。jvm的脉络梳理需要找到一个切入点,然后将所有的知识点串联起来。

刚学习java的时候,老师通过txt写一段经典的程序Hellow word,经过了几个步骤,安装jdk、打开记事本编写一段hellow word代码保存为Test.java、然后cmd 运行javac Test.java、再运行 java Test、然后控制台就输出了这段Hellow word。

以上虽然是一段最简单的程序,但是对于java来说却经历了最全的几个重要阶段;

  1. 编码阶段

    源码编写阶段,主要用到了jdk(Java Development Kit)中封装好的api方法。

  2. 编译阶段

    本阶段也称之为前端编译阶段,将编写好的java源文件编译成.class字节码,主要用到jdk中的javac编译器。

  3. 执行阶段

    执行阶段主要是靠jre(Java Runtime Environment)java运行时环境。jre分为bin、lib两个目录,bin认为就是jvm,lib是.class后缀的基本类库。在运行我们的.class文件时需要依赖的。那么执行阶段就是jvm的重头戏。

    那么执行阶段jvm都做的哪些事情,首先jvm需要将编译好的.class字节码加载运行时数据区,再通过执行引擎执行。

通过以上三个阶段就能解决java第一个特性,Write Once,Run Anywhere。如图;


还有一个特性就是内存自动管理,不需要开发人员操心对象应该分配多大内存(内存自动分配),和哪些内存需要回收(Garbage Collection)。如图;

通过上面描述的Hellow word 就已经将这本书讲到的jvm的核心知识点基本上都很清楚的(黑色加粗字体)罗列出来了,为什么把jdk和jre也标记出来的原因是有些牛逼(无脑)面试官会问,比如两个的区别。通过一个示例的切入点整理出了jvm的知识体系枝干,按照顺序整理。

  • 前端编译阶段:虽然不属于jvm负责的事,但是本书里面也详细提到了(第10章 前端编译与优化),所以接下来也总结一下。

  • .class字节码:class字节码生成也不属于jvm的事,归jdk的javac编译器。本书也详细提到了(第6章 类文件结构),所以。

  • .class字节码加载:这个属于jvm的活,(第7章 虚拟机类加载机制)以及(第9章 类加载及执行子系统的案例与事件),讲了一些有名的容器用到了类加载。

  • 运行时数据区:纯jvm的活,也是面试重点。(第2章 内存区域与内存溢出)

  • 自动内存管理:纯jvm的活,分为内存自动分配、垃圾回收也是面试重点。(第3章 垃圾收集器与内存分配策略)以及一些调优实践(第4章 虚拟机性能监控、故障处理工具)(第5章 调优案例分析与实践)。

  • 执行引擎:纯jvm的活,除了对虚拟机字节码解释执行外,还会对一些热点逻辑做优化编译为本地机器码。本书(第8章 虚拟机字节码执行引擎)和(第11章 后端编译与优化)以及(第9章 类加载及执行子系统的案例与事件)。看图;

这就是个人理解的脉络,按照这个脉络再针对每个点详细学习总结。本书最后一部分讲到了高效并发,也是面试重地,最后总结。

会当凌绝顶、一览众山小

本书看了两遍,第一遍从第二章看到结尾,第二遍从结尾看到第二章,第一遍很蒙,第二遍好点,但是脑海里也仅仅停留着某个章节某些点很零散,借用本书的比喻就是一堆零散的点找不到根,分分中被干掉真的记不住。当我开始总结这篇笔记的时候已经第三遍开始了。可能是因为看两遍之后才有的感觉,找到切入点,捋清楚脉络,俯视这些章节知识点的时候会感觉轻松很多,也不会那么的抵触,带着问题读书会更有效率吧。

这张图就是站在山顶描绘的全貌,接下来的时间里还是需要反复读本书,不断总结不断学习。最终目的不仅仅是为了浮于表面只针对概念侃侃而谈,而是真正的要能应用到实际应用中,去解决实际的问题。

前端编译与优化

前端编译是将各种语言(java、JRuby、Croovy等语言)变异成.class字节码。

那么java前端编译指的就是javac,或者说是Eclipse JDT中的增量式编译器(ECJ),ECJ具体不了解应该就是另一种java前端编译器。以下描述的前端编译只针对java,其他的不了解。

前端编译期间除了将java文件编译成为了.class文件,同时也做了优化。这个优化只针对程序员开发效率层面的优化,比如java语法增加了很多语法糖前端优化负责解糖,让开发人员在写代码的时候提高效率。而运行效率方面的优化不由前端编译负责,而是由后端编译负责。java这样设计的原因是第二个梦想,希望不仅java语言能运行在jvm上,其他语言也可以运行在jvm上,只是前端编译实现不同而生成的.class字节码相同。

javac源码与调试

javac源码在 openjdk7/langtools/src/share/classes/com/sun/tools/javac中。到了jdk9以后整个jdk所有类库都采用模块化重构了/src/jdk.compiler/share/classes/com/sun/tools/javac。本书将的是jdk9之前。

javac编译器除了jkd类库外,就只引用了/langtools/src/share/classes/com/sun/*;里面的代码,所以通过Eclipse,先建立一个Compiler_javac的java工程,然后把从com以后的代码都拷贝到工程src下面即可。


通过com.sun.tools.javac.Main 的 main()方法就可以执行了,编译文件的参数在Run Configurations面板中的Arguments页签中指定


javac编译过程

javac代码编译过程分为1个准备过程和3个处理过程;

1)准备过程:初始化插入式注解处理器。

2)解析与填充符号表过程,包括:

  • 词法、语法分析。将源代码的字符流转变为标记集合,构造出抽象语法树。

  • 填充符号表。产生符号地址和符号信息。

3)插入式注解处理器的注解处理过程:插入式注解处理器的执行阶段。

4)分析与字节码生成过程,包括:

  • 标注检查。对语法的静态信息进行检查。

  • 数据流及控制流分析。对程序动态运行过程进行检查。

  • 解语法糖。将简化代码编写的语法糖还原为原有的形式(拆装箱、泛型擦除、变长参数)。

  • 字节码生成。将前面各个步骤所生成的信息转化成字节码。

插入式注解是开发人员可以干预的。通过继承AbstractProcessor处理编译期间对抽象语法树修改。

解析与填充符号表

1.词法、语法分析

词法分析是将源代码的字符流转变为标记集合,构造抽象语法树。单个字符是程序编写时的最小元素,而标记则是编译时的最小元素,关键字、变量名、字面量、运算符都是标记;int a = b + 2 这句代码就6个标记。javac源码中,词法分析过程由com.sun.tools.javac.parser.Scanner类实现。

语法分析是根据标记序列构造抽象语法树的过程

Lombok原理分析与功能实现 (mythsman.com)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章