jvm
司青-已停止更新
本博客已停更;
展开
-
[Golang实现JVM第七篇]实现invokevirtual和虚方法表
本篇我们专注invokevirtual这一条指令,先通过简单粗暴的方式实现指令的功能,然后探究如何通过著名的虚方法表(Virtual Method Table)来进行一些优化。指令含义invokevirtual用于调用除静态方法、构造方法、私有方法、接口方法外的所有方法。其指令的格式为:invokevirtual = 182 (0xb6)Format:invokevirtual indexbyte1 indexbyte2Operand Stack:..., objectref, [arg1原创 2020-10-09 20:12:02 · 867 阅读 · 0 评论 -
从JVM角度看为什么final字段可以“延迟“到构造方法中初始化
我们都知道在Java中final字段都是要在定义时完成初始化工作的,否则通不过编译。但是有一处例外,那就是对于对象的字段来说final字段可以"延迟"到构造方法,或者static {}语句块中初始化,例如下面的代码public class FinalTest { private static final Object staticObj; private final Object noneStatic; static { staticObj = new Objec原创 2020-09-01 19:42:04 · 491 阅读 · 0 评论 -
[Golang实现JVM第六篇]实现Native方法
首先需要明确几个问题。没有Native方法JVM什么也做不了可能很多人认为native方法是Java里的禁区,使用本地方法会牺牲可移植性,而且还会有额外开销,貌似几乎没有程序员会在实际项目中写本地方法,这玩意就是个很冷门的东西。其实这种看法是错误的,哪怕一个Hello Word程序都是要严重依赖于本地方法的。在JDK中,你会发现任何涉及到I/O、线程操作的类,层层追踪源码后最终都能找到一个对应的native调用,真正把Hello World打印到控制台的正是这些native方法。而用于启动线程的Thre原创 2020-08-24 16:39:45 · 868 阅读 · 0 评论 -
[Golang实现JVM第五篇]静态方法调用的实现
一直以来又长又臭的调用链简直就是Java语言的标志性特色,方法调用可谓是Java世界里表达一切逻辑的基石。现在我们终于具备了实现它的基础。JVM中的5条方法调用指令在JVM中触发方法调用的指令有5条,分别是:invokestatic调用静态方法invokespecial调用构造方法invokeinterface调用接口方法invokevirtual调用对象方法invokedynamicjdk1.7中引入,给动态语言预留的调用指令。指令的第一个参数不再是代表方法符号原创 2020-07-08 15:50:47 · 580 阅读 · 2 评论 -
[Golang实现JVM第四篇] 整数加法和条件判断指令的实现
在上一篇中我们实现了一个能跑的解释器,支持了一些基本的栈操作指令。现在我们就可以开始实现"有点用"的数学运算和条件判断了。github: https://github.com/wanghongfei/mini-jvm局部变量表、程序计数器由于JVM字节码是基于栈的指令集,因此一切操作都是以栈为基础的,也就是说计算1+1,那需要先在栈中压入两个1然后进行计算,如果是对象方法调用,那么对象的引用、方法参数都会事先被压入栈中。除栈外还有一个跟执行相关的重要结构就是局部变量表(Local Variable T原创 2020-07-02 14:11:37 · 369 阅读 · 0 评论 -
[Golang实现JVM第三篇] 解释器雏形
在上一篇中我们已经完成了class文件的解析工作,虽然没有解析所有的属性,但是已经足够支持一些基本的算法题Java代码编译生成的class文件了。有了这一步,日后如果遇到新的特性需要支持,只需缺哪补哪,补上对应属性的解析逻辑就可以了。下一步就是实现一个基本的执行引擎,即解释器,并且支持基本的栈操作相关的指令,比如iconst_x, istore_x, bipush等。基于栈的指令集和基于寄存器的指令集JVM字节码是一套基于栈的指令集,也就是说操作数栈是一切计算的基本容器,大部分指令都是围绕着操作数栈展开原创 2020-06-15 16:43:35 · 473 阅读 · 0 评论 -
[Golang实现JVM第二篇]解析class文件是万里长征第一步
正确解析class文件是万里长征第一步。本篇我们会全程使用golang完成class文件的解析工作。数据类型JVM的class文件完全是二进制文件,最小单位是字节,也有数据类型,但都是字节的整数倍(废话)。规范中class文件一共有两类数据,一种是无符号整数,一种是表。无符号整数一共有u1,u2, u4, u8四种类型,分别表示8bit, 16bit, 32bit, 64bit的无符号整数。表则是无符号整数的集合,class文件中在出现表之前都会先跟着一个u2类型的长度数据,表名后面表的总长度,这样才能原创 2020-05-27 10:40:10 · 498 阅读 · 0 评论 -
【用Golang实现JVM第一篇】知识准备&前言
学习JVM最好的方法,就是实现它,没有之一。对JVM感兴趣的朋友可能会去主动寻找讲解JVM的书,比如《深入理解JVM》、《Java虚拟机规范》、《虚拟机的设计与实现》,但是这些书都是定性讲解,多数人看过以后对不少概念还是会很模糊,其根本原因就是我们无法只根据定义在脑袋里想象出具体用代码应该怎么实现,就会有一种空中楼阁的感觉。既然虚拟机规范都是公开的,为什么我们不尝试着去实现一个能跑就行的JVM呢?方法论:将复杂问题化解为简单问题的集合国外有一本著名的操作系统教材,叫作《Operating System原创 2020-05-26 15:08:28 · 758 阅读 · 0 评论 -
JEP 333: 一个可伸缩的低延迟垃圾收集器
译者:王鸿飞摘要Z垃圾收回器,也被称为 ZGC, 是一种可伸缩的低延迟垃圾收集器。目标垃圾回收停顿时间不超过10ms无论是相对小的堆(几百MB)还是大堆(TB级)都能应对自如与G1相比,吞吐量下降不超过15%方便日后在此基础上实现新的gc特性、利用colored pointers(译者注:暂时翻译为彩色指针)和读屏障进一步优化收集器支持Linux/64平台我...翻译 2018-06-25 20:13:39 · 766 阅读 · 0 评论 -
Java中为什么finally语句块一定会被执行?
通过阅读JVM规范,得知编译器是通过冗余来实现finally语句块的。我们可以写段代码做一个验证。JDK版本:8 如下面的代码:import java.io.*;public class Main { public static void main(String[] args) { try { foo(); } catch (IOEx原创 2015-08-29 22:46:34 · 4868 阅读 · 2 评论