ym网站源码分享 2020网站源码

大家好,今天来为大家分享ym网站源码分享的一些知识点,和2020网站源码的问题解析,大家要是都明白,那么可以忽略,如果不太清楚的话可以看看本篇文章,相信很大概率可以解决您的问题,接下来我们就一起来看看吧!

专注于Java领域优质技术号,欢迎关注

作者:老曹撸代码

1.前言

没错这又是一篇介绍JVM的文章,这类文章网上已经很多,不同角度、不同深度、不同广度,也都不乏优秀的。为什么还要来一篇?首先对于我来说,我正在学习Java,了解JVM的实现对学习Java当然很有必要,但我已经做了多年C++开发,就算我用C++实现一个JVM,我还是个C++码农,而用Java实现,即能学习Java语法,又能理解JVM,一举两得。其次,作为读者,hotspot或者其他成熟JVM实现的源码读起来并不轻松,特别是对没有C/C++经验的人来说,如果只是想快速了解JVM的工作原理,并且希望运行和调试一下JVM的代码来加深理解,那么这篇文章可能更合适。

我将用Java实现一个JAVA虚拟机(源码在这下载:https://github.com/caoym/jjvm,加Star亦可),一开始它会非常简单,实际上简单得只够运行HelloWorld。虽然简单,但是我尽量让其符合JVM标准,目前主要参考依据是《Java虚拟机规范(JavaSE7中文版)》。

2.准备

先写一个HelloWorld,代码如下:

我期望所实现的虚拟机(姑且命名为JJvm吧),可以通过以下命令运行:

接下来我们开始实现JJvm,下面是其入口代码,后面将逐步介绍:

3.加载初始类

我们将包含main入口的类称为初始类,JJvm首先需要根据org.caoym.HelloWorld类名,找到.class文件,然后加载并解析、校验字节码,这些步骤正是ClassLoader(类加载器)做的事情。HelloWorld.class内容大致如下:

没错是紧凑的二进制格式,需要按规范解析,不过我并不打算自己写解析程序,可以直接用com.sun.tools.classfile.ClassFile,这也是用JAVA写好处。下面是HelloWorld.class解析后的内容(通过javap-vHelloWorld.class输出):

可以看到HelloWorld.class文件中主要包含几部分:

常量池(Constantpool)常量池中记录了当前类中用到的常量,包括方法名、类名、字符串常量等,如:23,#3为此常量的索引,字节码执行时通过此索引获取此常量,String为常量类型,还可以是Methodref(方法引用)、Fieldref(属性引用)等。方法定义此处定义了方法的访问方式(如PUBLIC、STATIC)、字节码等,关于字节码的执行方式将在后面介绍。

以下为类加载器的部分代码实现:

类加载器可以加载两种形式的类:JvmOpcodeClass和JvmNativeClass,均继承自JvmClass。其中JvmOpcodeClass表示用户定义的类,通过字节码执行,也就是这个例子中的HelloWorld;JvmNativeClass表示JVM提供的原生类,可直接调用原生类执行,比如java.lang.System。这里把所有非项目内的类,都当做原始类处理,以便简化虚拟机的实现。

4.找到入口方法

JVM规定入口是staticpublicvoidmain(String[]),为了能够查找指定类的方法,JvmOpcodeClass和JvmNativeClass都需要提供getMethod方法,当然main方法肯定存在JvmOpcodeClass中:

5.执行非Native(字节码定义的)方法

下图为以HelloWorld的main()方法的执行过程:

下面将详细说明。

5.1.虚拟机栈

每一个虚拟机线程都有自己私有的虚拟机栈(JavaVirtualMachineStack),用于存储栈帧。每一次方法调用,即产生一个新的栈帧,并推入栈顶,函数返回后,此栈帧从栈顶推出。以下为JJvm中虚拟机栈的部分代码:

5.2.栈帧

栈帧用于保存当前函数调用的上下文信息,以下为JJvm中栈帧的部分代码:

说明:

局部变量表保存当前方法的局部变量、实例的this指针和方法的实参。函数执行过程中,部分字节码会操作或读取局部变量表。局部变量表的长度由编译期决定。常量池引用当前类的常量池。字节码内容以数组形式保存的当期方法的字节码。程序计数器记录当前真在执行的字节码的位置。操作数栈操作数栈用来准备字节码调用时的参数并接收其返回结果,操作数栈的长度由编译期决定。

5.3.方法调用

方法调用的过程大致如下:

新建栈帧,并推入虚拟机栈。将实例的this和当前方法的实参设置到栈帧的局部变量表中。解释执行方法的字节码。

以下为JJvm中的部分代码:

5.4.解释执行字节码

字节码的执行过程如下:

获取栈顶的第一个栈帧。获取当前栈的程序计数器(PC,其默认值为0)指向的字节码,程序计数器+1。执行上一步获取的字节码,推出操作数栈的元素,作为其参数,执行字节码。字节码返回的值(如果有),重新推入操作数栈。如果操作数为return等,则设置栈帧为已返回状态。如果操作数为invokevirtual等嵌套调用其他方法,则创建新的栈帧,并回到第一步。如果栈帧已设置为返回,则将返回值推入上一个栈帧的操作数栈,并推出当前栈。重复执行1~7,直到虚拟机栈为空。

以下为JJvm中解释执行字节码的部分代码:

6.执行Native方法

Native方法的调用要更简单一些,只需调用已存在的实现即可,代码如下:

7.结束

到目前为止,我们的“刚好够运行HelloWorld”的JVM已经完成,完整代码可在这里下载:https://github.com/caoym/jjvm。当然这个JVM并不完整,缺少很多内容,如类和实例的初始化、多线程问题、反射、GC等等。我争取逐步完善JJvm,并奉上更多文章。

来源:https://www.jianshu.com/p/4d81465c2fb8

关于ym网站源码分享,2020网站源码的介绍到此结束,希望对大家有所帮助。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平