本文介绍了一下Hotspot,以及自身在代码阅读时的一些感受。

本文章节

缘起

感谢开源的兴起,让我看到其他优秀程序员所写的代码。但一些开源项目由于代码的规模比较大,所以对这些代码的理解有难度。我自己在阅读Hotspot代码时,也获取了很多人的帮助,而且通过讲诉你对代码的理解,也容易发现自己对代码的理解是否出现偏差。分享,让知识变得更为准确,而且也更有意义起来。

我在文章的底部列出我看过的比较重要的资料,如果我的文章引用了您的观点,但我却没有点明,请您告诉我,这是失误,但这不是故意的。因为尊重别人的知识,重要!

Hotspot是什么?

程序员应该都知道Java, 但可能不一定听过Hotspot。比如我:我之前是不知道有Hotspot的,但那个时候,我用Java已经有两年了。Java早在上个世纪就出现了,而在这个世纪,他的养父Sun没钱了,于是把他过继给Oracle。

Java在运行时,需要Java的运行时环境,这个道理和Microsoft的C#是一样的。就目前而言,Oracle有两套支持Java运行时环境:一套叫标准JDK;另一套是开源的,叫Openjdk。这两个版本有些差异,这是因为Openjdk是开源的缘故,当部分代码涉及到商业方面的利益时,它需要避开,比如GPEG库。我分析的是Oracle关于Java 7的开源实现——Openjdk7 的代码。Hotspot就是Openjdk7的核心代码。有人说Java 8都出来了,你分析Java 7的实现,不会有些落后吗?放心,这些核心代码Oracle一般不会剧烈变动,否则维护、以及商业所要求的稳定性都是个问题。

代码阅读

阅读源码的能力很重要!!!想象一下,像鲁迅、钱钟书这种有成就的大家,成长的过程中没有读过红楼梦,没有读过三国演义,没有读过史记?但奇怪的是,在学校里却很少有人强调这点,好像我们天生出去就能写代码似的。这就好像我们去KTV,拿起话筒就唱,但这个杀猪的调调和我是歌手是同一个意义吗?所以,为了不写出“杀猪”一样的代码,读些优秀的代码还是比较好的。源码阅读是一种能力,是需要培养的!

本节简单的介绍一下如何阅读代码。这个话题有些仁者见仁,智者见智的意思。关于代码阅读有一本书——《代码阅读》。我2010年前后看了这本书。老实讲,没什么太大的感受,可能因为那会我没有阅读过足够的代码,所以这本书没有引起我的共鸣,但我打算以后有时间,再看一下。

在我看来,代码阅读是一种能力,你需要用心去培养;你也不能指望只看别人的经验就能获取这种能力。这就好比游泳,你在岸上明白了游泳的原理,但你终究要下到水里,才能真的学会游泳。在这里我说一下我是如何来看代码的

  1. 代码分析的环境

    代码分析环境主要指代码的静态分析和代码的运行时分析。静态分析就是浏览源代码;而代码的运行时分析,是指你编译源码并且使用测试用例分析代码的行为,或使用调试工具对代码进行单步跟踪。

    如果你目前觉得建立代码的运行时分析环境比较麻烦,比如在Linux环境下,可能会有库依赖的问题、编译等问题,这种情况下,你可以暂时先放放,等你对代码的静态分析到一定程度,你觉得必须要进行代码的运行时分析才能明白代码的意思时,那个时候你再去折腾,比较不会打击你的积极性(我觉得不管做什么,一定要注意保护好积极性,也就是好奇心和兴趣)。

  2. 代码分析的起点

    代码分析从什么地方开始呢?我觉得代码的启动流程分析会是一个比较好的代码分析入口点。因为,启动流程分析一来不会太难;另一面,可以帮你大概浏览一下整个代码的概况。比如,我对V8的分析就是先从代码的启动流程开始分析的。

  3. 代码分析如何更进一步

    代码都是由各种模块组成,这个时候你需要从网上收集一下待阅读代码的各个模块有哪些,这用来确认阅读代码的目标和方向。比如在Hotspot中,有解释器的结构和运行流程、垃圾回收机制、垃圾回收机制和其它模块的配合、优化编译器的结构和运行流程、底层的汇编器如何实现、ad文件是什么等等。这些信息一般网上都有,但不会太详细,但可以让你大概了解一下各个模块的概况。这个时候可以选取你感兴趣的,而目当前又有能力做分析的模块来进行。如果你建立了代码的动态分析环境,可以尝试对代码进行修改或者尝试独立代码的某一部分

  4. 代码分析要注意的问题

    看规模比较大的代码,刚开始可能会有些畏惧心理或者怎么看也看不懂,此时就需要耐心。我觉得可以选取一定规模代码量的开源项目一直看,不要老换,比如这里的Hotspot。开始时肯定不容易的,但当你一直看时,你就会慢慢地对你要看的代码熟悉起来,这时畏惧感就没了。

    另外,代码即使看不懂,那也没什么,先跳过去,继续看。因为,有时代码的运行路线很多,你追着追着就发现找不着北了,这是因为你所看的代码正在发散,还没有到收敛的时候。一条线一条线的追,当某个时候,你发现你追踪的代码路线和另一个路线重合了,那么此时就是代码收敛的时候,你离理解也就不远了。

    在分析开源代码的时候,注意看一下测试,尤其是单元测试。比如我在做V8关于Disassemble本地代码时,就是从测试这一部分的单元测试开始的。一般开源代码都会有完备的测试集,所以有时需要注意一下是否可以从测试的角度撬开理解代码的大门。

  5. 代码分析的工具

    • Windows 平台:Insight Source 或者 Visual Studio + VassistX

    VS有一个编码问题。我找了很长时间,就是没有找到如何设置工程项目的编码。好不容易找到一个另存为的,可以在保存时设置编码,但是,只有utf-8的BOM形式。我的天!虽然vim可以识别这种情况,但在netbeans中使用git进行协作开发时,就会发现netbeans不解析这个文件了,WoW! 如果你要编辑的文件涉及到多人,且在linux上使用时,留意一下这一点。

    • Linux 平台: VIM + cscope + ctags

      1. 生成待分析的文件名列表

         find src -type f | grep  "*\.cc\|*\.cpp" > tags.file
        
      2. 依据待生成文件列表,生成tag文件

         ctags -L tags.file
        
      3. 生成cscope数据库文件cscope.out

         cscope -itags.file -b -q -k
         export CSCOPE_DB=./cscope.out
        

参考资料

  1. 深入理解Java虚拟机 (*)
  2. Java_Program_In_Action 莫枢(*)
  3. JavaSE 7 虚拟机规范 (*)
  4. jvm高级特性与实践 周志明
  5. Hotspot实战