
写自己的JVM
文章平均质量分 92
Java虚拟机非常复杂,要想真正理解它的工作原理,最好的方式就是自己动手写一个。但是这个系列的定位还是入门,所以有很多的东西暂时都不会实现,比如 malloc,GC,多线程,native interface等。主要的目的还是在于大致了解JVM是一个什么样的东西,这也是我采用java来实现JVM的一个
二手的程序员
这个作者很懒,什么都没留下…
展开
-
写自己的JVM(0xA)-异常处理
异常处理是Java语言非常重要的一个语法,我们从Java虚拟机的角度来讨论异常是如何被抛出和处理的。原创 2023-12-06 09:27:45 · 947 阅读 · 0 评论 -
写自己的JVM(0x9)
项目地址:Jvm在启动一个程序的时候,会涉及到非常多的内容,其中就有一些JNI方法。可以看出是使用了 native 方法来实现变量的赋值。如果想真正的实现 System.out.println 方法,我们就需要实现这些JNI方法。原创 2023-12-05 09:36:13 · 915 阅读 · 0 评论 -
写自己的JVM(0x8)
数组在Java虚拟机中是个比较特殊的概念。为什么这么说呢?有下面几个原因:首先,数组类和普通的类是不同的。普通的类从class文件中加载,但是数组类由Java虚拟机在运行时生成。数组的类名是左方括号([)+数组元素的类型描述符;数组的类型描述符就是类名本身。例如,int[]的类名是[Iint[][]的类名是[[IObject[]的类名是String[][]的类名是等等。其次,创建数组的方式和创建普通对象的方式不同。普通对象由new指令创建,然后由构造函数初始化。基本类型数组由newarray指令创建;原创 2023-12-04 12:05:39 · 873 阅读 · 0 评论 -
写自己的JVM(0x7)-invokedynamic指令
原始博客的地址:该项目的地址:上一篇我们实现了方法调用以及参数传递,主要讨论了四个invoke指令。但是有一条指令我们没有讨论,那就是在JDK 7里面新增的指令。这条新增加指令的目标:实现动态类型语言(Dynamically Typed Language)支持而进行的改进之一,也是为JDK 8里可以顺利实现Lambda表达式而做的技术储备。原创 2023-12-01 10:26:13 · 914 阅读 · 0 评论 -
写自己的JVM(0x6)- 方法调用与参数传递
原始博客的地址:该项目的地址:前面我们基本完成了方法区的实现,现在我们需要搞定方法的调用。在Java虚拟机支持以下5条方法调用字节码指令,分别是:invokestatic:用于调用静态方法。invokespecial:用于调用实例构造器()方法、私有方法和父类中的方法。invokevirtual:用于调用所有的虚方法。invokeinterface:用于调用接口方法,会在运行时再确定一个实现该接口的对象。原创 2023-11-30 10:17:07 · 885 阅读 · 0 评论 -
写自己的JVM(0x5)
原始博客的地址:该项目的地址:这一篇,我们主要是实现方法区(现在叫元数据区)里面的东西。方法区主要存放从class文件获取的类信息。此外,类变量也存放在方法区中。当Java虚拟机第一次使用某个类时,它会搜索类路径,找到相应的class文件,然后读取并解析class文件,把相关信息放进方法区。放进方法区的东西有:常量池类信息字段信息方法信息类加载器,超类,接口等等其实这些信息在之前我们解析 class 文件的时候都遇到过。现在只不过我们换一种形式来表示这些信息。原创 2023-11-29 09:45:14 · 1025 阅读 · 1 评论 -
写自己的JVM(0x4)- 实现一个解释器
通常将指令分为两部分:操作符操作数每条指令都以一个单字节的操作码(opcode)开头,这意味着Java虚拟机最多只能支持256条指令。Java虚拟机规范给每个操作码都指定了一个助记符(mnemonic)。比如操作码是0x00这条指令,因为它什么也不做,所以它的助记符是nop(no operation)。JVM的指令中,操作数不是固定的,可能有0个,1个,2个等等。原创 2023-11-28 11:28:51 · 1056 阅读 · 0 评论 -
写自己的JVM(0x3)
原始博客的地址:该项目的地址:有了前面2篇的基础,现在我们终于有能力进入正题了。我们先来看一张图:相信大家对这张图还是比较熟悉的,今天我们主要的目的就是搭建一个运行数据区的框架出来。方法区:这一块内容我们到后面再说,暂时简单理解为它就是存放了 class。原创 2023-11-28 11:25:55 · 833 阅读 · 0 评论 -
写自己的JVM(0x2)
常量池可以看成是一个表,但是有三点需要特别注意。表头给出的常量池大小比实际大1。假设表头给出的值是n,那么常量池的实际大小是n–1。有效的常量池索引是1~n–1。0是无效索引,表示不指向任何常量。和各占两个位置。u1 info[];可以看出,每一项都包含一个 tag,一个 info 数组。info 数组里面的的具体内容与 tag 的值有关。tag 的值分为以下几种:tag取值很多,就举一个例子,其他的都是类似的。u1 tag;name_index。原创 2023-11-28 11:16:55 · 381 阅读 · 0 评论 -
写自己的JVM(0x1)
看上图,类加载子系统将 class 文件加载到内存中,这个过程需要完成2件事:找到 class 文件的路径将 class 文件按照格式解析这篇文章,主要是完成第1件事,寻找 class 文件。本章讨论了Java虚拟机从哪里寻找class文件,对类路径有了较为深入的了解,并且把抽象的类路径概念转变成了具体的代码。下一章将研究class文件格式,实现class文件解析。原创 2023-11-28 11:15:08 · 878 阅读 · 0 评论