Top Banner
Kris Mok, Software Engineer, Taobao @rednaxelafx 莫莫 /“ 莫莫”
57

为啥别读HotSpot VM的源码(2012-03-03)

Jan 15, 2015

Download

Technology

Kris Mok

第0次JVM源码阅读活动

分享目标

* 让VM相关基础知识尚浅的人找到阅读HotSpot VM源码之外的学习JVM的路径
* 让并不真的对VM内部实现细节感兴趣的人不必在源码上耗费精力

* 为后续活动做准备
* 确定活动周期、形式、目标受众
* 吸引同好报名分享阅读VM源码的经验
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 为啥别读HotSpot VM的源码(2012-03-03)

Kris Mok, Software Engineer, Taobao@rednaxelafx莫枢 /“ 撒迦”

Page 2: 为啥别读HotSpot VM的源码(2012-03-03)

为啥别读 HotSpot VM 的源码

第 0 次 JVM 源码阅读活动

阿里巴巴集团 - 技术共享平台 -

核心系统研发 - 专用计算组莫枢(撒迦)2012-03-03

Page 3: 为啥别读HotSpot VM的源码(2012-03-03)

关于我…• 2009 年毕业自南京大学软件学院• 同年 10 月加入淘宝• 目前在参与 JVM 相关研发• 编程语言的设计与实现爱好者

• 希望与各位同好多交流!– 博客: http://rednaxelafx.iteye.com/– 新浪微博: http://weibo.com/rednaxelafx– 高级语言虚拟机群组: http://hllvm.group.iteye.com/– JVM 源码阅读活动微群: http://q.weibo.com/1823766

Page 4: 为啥别读HotSpot VM的源码(2012-03-03)

分享目标( I )• 让 VM 相关基础知识尚浅的人找到阅读

HotSpot VM 源码之外的学习 JVM 的路径

• 让并不真的对 VM 内部实现细节感兴趣的人不必在源码上耗费精力

Page 5: 为啥别读HotSpot VM的源码(2012-03-03)

分享目标( II )• 为后续活动做准备– 确定活动周期、形式、目标受众– 吸引同好报名分享阅读 VM 源码的经验

Page 6: 为啥别读HotSpot VM的源码(2012-03-03)

突击提问• 已读过或正在读 OpenJDK 的源码?• 已读过或正在读其它 VM 的源码?• 有兴趣自己动手实现 VM ?• 有编译器 / 解释器的实现经验?

Page 7: 为啥别读HotSpot VM的源码(2012-03-03)

突击提问( II )• PermGen– a. 不知道是什么?– b. 在“堆内”?– c. 在“堆外”?– d. 不关心?

Page 8: 为啥别读HotSpot VM的源码(2012-03-03)

为啥要读 HotSpot VM 的源码?

• 生产环境使用 Oracle/Sun JDK 或OpenJDK– 读源码有助解决问题(真能么?)

• 三大主流高性能 JVM 中唯一开源的– 另外两个的源码也读不到

• 想修炼内功– “ 现实”驱动还是真感兴趣?

• 找点乐子• 其它

Page 9: 为啥别读HotSpot VM的源码(2012-03-03)

读 HotSpot VM 源码想了解什么?

• JVM crash 了!为什么?怎么办?• JVM 报 OutOfMemoryError 了 …

• 想学习如何操纵字节码• “ 这段代码创建了多少个对象”?• “JVM 会让 String 共享 char[]” ?

• 其它

Page 10: 为啥别读HotSpot VM的源码(2012-03-03)

理想与现实( I )

例子:JVM 的架构与知识点

Page 11: 为啥别读HotSpot VM的源码(2012-03-03)

概念中 JVM 的结构类加载器

子系统

内存空间

方法区 Java 堆 Java栈

本地方法栈

自动内存管理

指令计数器以及其它

隐含寄存器执行引擎

地址 数据和指令

本地方法接口 本地方法库

Class文件

Page 12: 为啥别读HotSpot VM的源码(2012-03-03)

某个 JVM 实现的架构

Page 13: 为啥别读HotSpot VM的源码(2012-03-03)

HotSpot Server Compiler 的优化

Page 14: 为啥别读HotSpot VM的源码(2012-03-03)

理想与现实( II )

例子:iadd 字节码指令的实现

Page 15: 为啥别读HotSpot VM的源码(2012-03-03)

例:概念

JVM规范所规定的抽象行为

value2

value1value1 + value2

value1

1) pop

2) pop

3) add

4) push

value2

+

Page 16: 为啥别读HotSpot VM的源码(2012-03-03)

例:理想——简单直观

case SVM_INSTRUCTION_IADD: { /* instruction body */ jint value1 = stack[stack_size - 2].jint; jint value2 = stack[--stack_size].jint; stack[stack_size - 1].jint = value1 + value2;

/* dispatch */ goto dispatch;}

取自 SableVM的switch版解释器(sablevm/src/libsablevm/instructions_switch.c)

①②

③④

Page 18: 为啥别读HotSpot VM的源码(2012-03-03)

例:现实——有点绕弯void TemplateTable::iop2(Operation op) { transition(itos, itos); switch (op) { case add : __ pop_i(rdx); __ addl (rax, rdx); break; case sub : __ movl(rdx, rax); __ pop_i(rax); __ subl (rax, rdx); break; case mul : __ pop_i(rdx); __ imull(rax, rdx); break; case _and : __ pop_i(rdx); __ andl (rax, rdx); break; case _or : __ pop_i(rdx); __ orl (rax, rdx); break; case _xor : __ pop_i(rdx); __ xorl (rax, rdx); break; case shl : __ movl(rcx, rax); __ pop_i(rax); __ shll (rax); break; case shr : __ movl(rcx, rax); __ pop_i(rax); __ sarl (rax); break; case ushr : __ movl(rcx, rax); __ pop_i(rax); __ shrl (rax); break; default : ShouldNotReachHere(); }}

取自 HotSpot VM的模板解释器,AMD64版

Page 19: 为啥别读HotSpot VM的源码(2012-03-03)

例:现实——很多细节void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) { if (left->is_single_cpu()) { Register lreg = left->as_register(); if (right->is_single_cpu()) { // cpu register - cpu register Register rreg = right->as_register(); switch (code) { case lir_add: __ addl (lreg, rreg); break; // ... } } else if (right->is_stack()) { // cpu register - stack Address raddr = frame_map()-> address_for_slot(right->single_stack_ix()); switch (code) { case lir_add: __ addl(lreg, raddr); break; // ... } } else if (right->is_constant()) { // cpu register - constant jint c = right->as_constant_ptr()->as_jint(); switch (code) { case lir_add: __ incrementl(lreg, c); break; // ... } } /* … */ } /* ... */}

取自 HotSpot VM的Client编译器,AMD64

Page 20: 为啥别读HotSpot VM的源码(2012-03-03)

不读HOTSPOT VM的源码learn JVM without reading HotSpot VM’s source code

Page 21: 为啥别读HotSpot VM的源码(2012-03-03)

为何不要读 HotSpot VM 的源码?

• 基础概念不扎实时–硬读复杂实现的源码对理解基础概念帮助不大–繁琐的实现细节反而会掩盖掉一些抽像概念

• 已有现成的阅读资料时– 读资料比读源码更容易吸收自己需要的信息• 因人而异

• 可参加“源码阅读活动”– 让别人读源码,等分享…?

Page 22: 为啥别读HotSpot VM的源码(2012-03-03)

不明就里读源码的坏处?

• 加深误解– 案例 1 : HotSpot VM的解释器是这样实现的!

• 主流平台上的 HotSpot VM 使用“模板解释器”,而非这里说的“ C++ 解释器”

– 案例 2 : HotSpot VM用内部地址实现Java对象的hashCode()!• oopDesc才是 HotSpot VM 中表示 Java 对象的类型;ciObject不是

• 浪费时间 / 精力– 读了但全然无法理解,还不如先不读– 有些细节知道了也没用(视目的而异)

Page 23: 为啥别读HotSpot VM的源码(2012-03-03)

如何不读 HotSpot VM 的源码

• 仅为了理解 Java 程序的行为?– 是否已了解 Java 语言层面的规定?

• 否 => 先读 Java语言规范– 是否已了解 JVM 的抽像概念?

• 否 => 先读 JVM规范– 已确定想关注的行为是特定于某个实现?

• 否 => 回到前面两点– 是否有关于该实现的行为的文字描述?

• 是 => 先读文字描述• 否 => 那…真的要读源码么?

Page 24: 为啥别读HotSpot VM的源码(2012-03-03)

如何不读 HotSpot VM 的源码(续)

• 仍然想深入学习 VM 的内部知识?– 阅读相关背景知识的书、论文、博客等• 能够(在读源码前)事先了解许多术语• 知道术语便于找到更多资料

– 阅读更简单一些的 VM 实现的源码• 循序渐进

– 自己动手写简单的编译器 /VM• 实践是检验真理的唯一标准

–最后…• 如果真的很有空才去读 HotSpot VM 的源码

Page 25: 为啥别读HotSpot VM的源码(2012-03-03)

如何不读 HotSpot VM 的源码(续)

• 工作就是鼓捣 HotSpot VM 的内部?–那真的得读代码,而且还得非常仔细地读–但动态调试比静态阅读代码更有助形象地理解– 入手顺序• 文档• 读代码• 做实验 +调试

Page 26: 为啥别读HotSpot VM的源码(2012-03-03)

其它 JVMalternative JVMs

Page 27: 为啥别读HotSpot VM的源码(2012-03-03)

KVM

• 项目主页:– http://java.sun.com/products/cldc/

• 介绍:– http://java.sun.com/products/cldc/wp/

简单小巧的 JVM

Page 28: 为啥别读HotSpot VM的源码(2012-03-03)

KVM (续)• 好处–包含 JVM 的最核心组件– 实现方式与 JVM规范所描述的抽象的 JVM 相近

• 坏处– 是 Java ME CLDC VM,而不是 Java SE VM–未实现反射、浮点数计算等功能

Page 29: 为啥别读HotSpot VM的源码(2012-03-03)

Maxine VM

• 项目主页:– http://labs.oracle.com/projects/maxine/

• 介绍:– https://wikis.oracle.com/download/attac

hments/4161575/The+Maxine+Virtual+Machine.pdf

纯 Java 实现的 JVM

Page 30: 为啥别读HotSpot VM的源码(2012-03-03)

Maxine VM (续)• 可在 IDE 里开发和调试• 二进制兼容性–可使用 Oracle JDK/OpenJDK的类库,兼容主

流 Java应用

Page 31: 为啥别读HotSpot VM的源码(2012-03-03)

Maxine VM (续)• 与 HotSpot VM 的部分对应关系– 对 HotSpot Client Compiler ( C1 )感兴趣

的,可以读 Maxine VM 里的 C1X来帮助理解• 可通过 C1Visualizer以图形界面更好的理解该编译

器的设计– 对 HotSpot Server Compiler ( C2 )里的

中间表现形式( Sea-of-nodes IR )感兴趣的,可以读 Maxine VM 里的 Graal来帮助理解• 可通过 IdealGraphVisualizer以图形界面理解该编

译器的设计

Page 34: 为啥别读HotSpot VM的源码(2012-03-03)

演示:IdealGraphVisualizer

Page 35: 为啥别读HotSpot VM的源码(2012-03-03)

VMKit / J3

• 项目主页:– http://vmkit.llvm.org/

• LLVM + MMTk + GNU Classpath

现成组件搭积木实现的 JVM

Page 36: 为啥别读HotSpot VM的源码(2012-03-03)

其它项目• 其它值得阅读源码的

JVM– Jikes RVM / MRP– JamVM– cacaovm– SableVM

• 其它值得阅读源码的非 JVM项目– ASM

• 其它值得实验的项目– BiteScript

Page 37: 为啥别读HotSpot VM的源码(2012-03-03)

推荐阅读recommended reading

Page 38: 为啥别读HotSpot VM的源码(2012-03-03)

VM 相关书堆…

Page 39: 为啥别读HotSpot VM的源码(2012-03-03)

我读过的 VM 相关书• 请参考豆瓣页面

http://book.douban.com/people/RednaxelaFX/all?tag=VM

• 基础知识主要靠这些书获得,通过自己写代码来理解

• 但比较深入的知识通常是从论文而不是书中获得的

• Anyway,规范一定要读!

Page 40: 为啥别读HotSpot VM的源码(2012-03-03)

计算机系统概论• http://book.douban.com/subject/2185

076/

Page 41: 为啥别读HotSpot VM的源码(2012-03-03)

深入理解计算机系统• http://book.douban.com/subject/5407

246/

Page 42: 为啥别读HotSpot VM的源码(2012-03-03)

程序设计语言——实践之路• http://book.douban.com/subject/2152

385/

Page 43: 为啥别读HotSpot VM的源码(2012-03-03)

虚拟机——系统与进程的通用平台

• http://book.douban.com/subject/1885761/

Page 44: 为啥别读HotSpot VM的源码(2012-03-03)

游戏脚本高级编程• http://book.douban.com/subject/1927

405/

Page 45: 为啥别读HotSpot VM的源码(2012-03-03)

Inside the Java 2 Virtual Machine

• http://book.douban.com/subject/1788390/

Page 46: 为啥别读HotSpot VM的源码(2012-03-03)

深入理解 Java 虚拟机• http://book.douban.com/subject/6522

893/

Page 47: 为啥别读HotSpot VM的源码(2012-03-03)

深入嵌入式 Java 虚拟机• http://book.douban.com/subject/1103

575/

Page 48: 为啥别读HotSpot VM的源码(2012-03-03)

Python 源码剖析• http://book.douban.com/subject/3117

898/

Page 49: 为啥别读HotSpot VM的源码(2012-03-03)

Shared Source CLI Essentials

• http://book.douban.com/subject/1484763/

Page 50: 为啥别读HotSpot VM的源码(2012-03-03)

编译原理 技术与工具• http://book.douban.com/subject/2970

069/

Page 51: 为啥别读HotSpot VM的源码(2012-03-03)

深度探索 C++ 对象模型• http://book.douban.com/subject/1091

086/

Page 52: 为啥别读HotSpot VM的源码(2012-03-03)

Oracle JRockit: The Definitive Guide

• http://book.douban.com/subject/4873919/

Page 53: 为啥别读HotSpot VM的源码(2012-03-03)

Java Performance

• http://book.douban.com/subject/5980062/

Page 54: 为啥别读HotSpot VM的源码(2012-03-03)

The Garbage Collection Handbook

• http://book.douban.com/subject/6809987/

Page 55: 为啥别读HotSpot VM的源码(2012-03-03)

The School of Niklaus Wirth

• http://book.douban.com/subject/3152171/

Page 56: 为啥别读HotSpot VM的源码(2012-03-03)

QUESTIONS?

Page 57: 为啥别读HotSpot VM的源码(2012-03-03)

Kris Mok, Software Engineer, Taobao@rednaxelafx莫枢 /“ 撒迦”