Sam的博客

欢迎来到我的博客

欢迎来到我的博客

2026-03-31

欢迎来到我的博客!这是我的第一篇文章。

阅读更多 →

手写JVM系列(18)异常处理机制

2018-01-20
标签:JVM

前面介绍了方法的调用过程,简单的方法可以在我们自己写的 JVM 中运行起来了,但是方法的执行过程并不完整,因为方法可能会抛出异常,我们暂时还无法处理异常。本节依然通过示例来讲解异常的处理机制。进一步完善我们的 JVM。核心是 athrow 指令的实现

阅读更多 →

手写JVM系列(17)本地方法的调用过程

2018-01-18
标签:JVMJNI

java 中有一些方法前面的关键字是native,该关键字修饰的方法表明当前方法不是由 java 实现的方法,而是由本地语言编写的。本地语言就是所在的操作系统所用的语言。因为一些和操作系统底层相关的方法是 java 无法实现的,或者基于性能的考虑,由 java 实现并没有用本地方法实现在执行效率上更高效,所以会用到本地方法。

阅读更多 →

手写JVM系列(16)反射机制简介

2018-01-18
标签:JVM

反射是 java 一个强大的机制,通过反射,我们可以动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。本节主要介绍反射机制中用到的类对象。

阅读更多 →

手写JVM系列(15)-字符串的实现

2018-01-16
标签:JVM

Java 程序中最常用的除了基本类型的变量,就数得上字符串了吧,String 在 Java 中并不是基本类型,而是一个引用类型,但是它又很特别,所以特意对 JVM 中的 String 进行讲解。但是不得不承认的是,我的示例中是用 java 来构建的 JVM,起初的目的就是为了快速实现该 JVM,快速的了解 JVM 内部原理,虽然达到了目标,但是在实现该 JVM 内部的一些细节时,总有些不尽人意的地方,这是当初所没想到的,例如本节字符串池的实现,以及后面本地方法的实现上,所写的代码都显得有点挫。不过对于理解 JVM 的内部原理,依然有很大帮助。

阅读更多 →

手写JVM系列(14)-数组的实现

2018-01-12
标签:JVM

前面介绍了类加载器的实现,目前我们已经可以加载普通的类,并创建该类的对象了,但是目前我们的 JVM 还不支持数组。数组类虽然也是类,但是其加载方式和之前所讲的通过 class 文件的形式加载是完全不同的,本节将介绍 JVM 中数组的实现,并完善我们的类加载器,使其可以加载数组。

阅读更多 →

手写JVM系列(13)-方法调用机制

2018-01-04
标签:JVM

我们知道一个程序的运行的逻辑就是在一个代码块中不断的调用方法,将这些方法的调用堆砌好之后就形成的程序的逻辑。有了前面介绍的知识基础,接下来就来介绍下方法的执行过程。本节的代码主要是在instructions-references包下的 invokeXXX 指令。同时也可以配合测试用例TestInvokeMethod08加深了解。

阅读更多 →

手写JVM系列(12)-类加载器的实现

2018-01-04
标签:JVM

通过之前的文章,我们了解了 Class 文件存储格式的具体细节,在 Class 文件中描述的各种信息,最终都需要加载到虚拟机中之后才能运行和使用。之前我们已经可以将 Class 文件的字节码读取到内存中了,这其实就是类加载器中 的加载过程,属于类加载器的一部分功能,除此之外,类加载器还有其它功能需要完善,这一节将对类加载的过程做一个详细的介绍。 本节的代码集中在 heap 包下。

阅读更多 →

手写JVM系列(11)-线程共享的运行时数据

2018-01-03
标签:JVM

前面已经初步实现了线程私有的运行时数据区,主要包括操作数栈和局部变量表。接下来将继续丰富运行时数据区的内容——线程共享的运行时数据区,包括方法区和运行时常量池。本节的代码集中在 heap 包下。同时也会对一些概念做出解释。因为自己之前在这些概念上的错误认识,走了很多弯路。

阅读更多 →

手写JVM系列(10)-解释器

2017-05-15
标签:JVM

上一节介绍了关于 JVM 指令集的相关知识,那么接下来我们就根据上一节介绍的知识,编写一个简易的解释器,读取字节码中的操作码和操作数,实现 JVM 规范中描述的指令集对应功能,从而完成简单方法的调用过程,并在接下来的章节中不断完善该解释器,使其支持更多指令。本节所实现的代码均在项目的 instructions 包下。

阅读更多 →

手写JVM系列(9)-指令集

2017-05-13
标签:JVM

编译之后的 Java 方法以字节码的形式存储在 class 文件中。前面已经初步实现了 Java 虚拟机栈、帧、操作数栈和局部变量表等运行时数据区。那么 JVM 是如何操作局部变量表和操作数栈中的数据呢?这就涉及到了 JVM 的字节码指令集。这一节对 JVM 的字节码指令集做一个介绍,本节所实现的指令位于项目的 instructions 包下。

阅读更多 →

手写JVM系列(8)-运行时数据

2017-05-12
标签:JVM

前面介绍了如何搜索和解析 class 文件,如何解析 class 文件,那么接下来就要开始实现 JVM 了,这一节我们讨论并初步实现运行时数据区(run-time data area),为接下来编写字节码解释器做准备。本节所有的代码均位于 runtimedata 包下。

阅读更多 →

手写JVM系列(7)-读取class文件

2017-05-10
标签:JVM

通过前面几节的讲解,我们已经基本了解了 class 文件的结构,每个字段代表什么含义,占多少字节,那么明确了 Class 文件的规则,接下来就可以读取 class 文件了,本节的代码均在项目的 classfile 包下。

阅读更多 →

手写JVM系列(6)-分析class文件-属性表

2017-05-09
标签:JVM

和常量池类似,各种属性表达的信息也各不相同,因此无法用统一的结构来定义。不同之处在于,常量是由 Java 虚拟机规范严格定义的,共有 14 种。但属性是可以扩展的,不同的虚拟机实现可以定义自己的属性类型。由于这个原因,Java 虚拟机规范没有使用 tag,而是使用属性名来区别不同的属性。属性数据放在属性名之后的 u1 表中,这样 Java 虚拟机实现就可以跳过自己无法识别的属性。

阅读更多 →

手写JVM系列(5)-分析class文件-常量池

2017-05-09
标签:JVM

常量池占据了 class 文件很大一部分数据,里面存放着各式各样的常量信息,包括数字和字符串常量、类和接口名、字段和方法名等。本节将详细介绍常量池和各种常量。

阅读更多 →

手写JVM系列(4)-分析class文件

2017-05-09
标签:JVM

前面一节已经介绍了如何获取了字节文件的字节流,那么在获取到字节流之后,就要读取并解析字节码了,这一节会介绍 class 文件的结构.本节的代码均在classfile包下,源码在这里

阅读更多 →

手写JVM系列(3)-搜索class文件

2017-05-08
标签:JVM

本节的目的是根据-cp命令指定的class路径以及后面的ClassName,找到对应的class文件,然后简单的打印出该 class 文件的字节码.完整源码classpath包中

阅读更多 →

手写JVM系列(2)-参数解析

2017-05-07
标签:JVM

这一章节开始JVM的编写,首先解决第一个问题,就是如何运行java程序,回想最开始学java时,写一个Hello.java的程序,使用javac Hello.java将源代码转换为class文件,然后使用java Hello运行程序。JVM是只认class文件的,如果想让JVM运行该Hello程序,就要通过java命令。本节将介绍java命令的常用方法,并实现java命令的解析。最终通过命令参数,读取对应的class数据。本节的代码均在classpath包下

阅读更多 →

手写JVM系列(1)-准备工作

2017-05-06
标签:JVM

本系列文章主要根据张秀宏老师的—— 《自己动手写 java 虚拟机》一书所做的笔记。该书实现了大部分 JVM 的功能,包括class文件解析、类加载、指令集、解释器、方法调用、数组和字符串的处理、异常处理等。这本书可以说是了解 Java 虚拟机最浅显易懂的书籍,随书提供了每个章节的代码,可以完美运行。但是这本书所附带的代码是用 go 语言书写的,如果想要看懂这本书的代码,首先要学会 go 语言的基本语法。这边博客记录了在阅读这本书之前的准备工作。我在练习中是根据张老师的代码用 Java 语言又实现了一遍。虽然用 Java 语言在实现一个自己的虚拟机,然后跑在自带的虚拟机上有点滑稽,但是重点还是了解虚拟机内部的基本原理。

阅读更多 →