【手写JVM专栏】二、搭建JVM框架,输出hello world

哈喽,大家好,我就是明明可以靠脸吃饭,却偏偏抢大家饭碗的硬核男人子牙老师。

本篇文章是专栏《用Java带你手写JVM》的第二篇。画人画皮先画骨,本篇文章咱们的目标是实现JVM框架,输出hello world。

是不是完全不知道代码怎么写?是不是就像当初学会Java不知道怎么做东西的感觉是一样的?这就是我说的虚拟机思维。把我这套课程跟完,把练习做做,慢慢地,你就有了虚拟机思维。这种思维对于你研究Hotspot或其他虚拟机,是非常非常非常有帮助的!


课程目标


本篇文章咱们要学习的目标就是在我们自己实现的JVM上成功运行这段Java代码
在这里插入图片描述
看下运行结果

在这里插入图片描述

前置知识


这部分很重要!很重要!很重要!

先说下JVM是如何运行这个Java程序的:

  1. JVM启动并完成初始化。Hotspot初始化做的事情很多很多,这里不细讲了。我之前研究的时候画了JVM启动流程图,需要的小伙伴可以关注公众号【硬核子牙】回复【JVM启动流程图】获取
  2. 完成类加载器的创建,然后去找main方法所在的类
  3. 触发加载阶段将硬盘上的字节码文件载入内存,进行解析,生成klass对象
  4. 根据方法名及方法描述符,在这个klass对象中找到main方法
  5. 构建方法运行环境
  6. 调用方法
  7. 调用完清理环境

你可以这样说,JVM是由五大模块组成:内存模型、类加载器子系统、执行引擎、垃圾收集器、JIT。JVM运行任何一个Java程序,除了垃圾收集器、JIT,其他三个模块是一定要参与的。这三个模块也是研究Hotspot源码必先攻克的知识点。如果你没有自己尝试着写过,直接去读Hotspot源码,我相信会是丈二和尚摸不着头脑。写过一遍再回头去研究,不说轻松看懂吧,至少能更容易理解一些思想及为什么要这样做。

JVM运行Java程序的七步中,一直没看到我提内存模型对吧。因为内存模型对于JVM实在太重要,重要到根本不需要提,它无处不在:类解析器解析生成的klass对象要存储到JVM管理的内存中,我们知道是元空间;类中的属性与方法,解析后也会生成独立的对象存储到JVM管理的内存中,方法在元空间,属性不在;JVM运行Java程序需要创建虚拟机栈;JVM调用Java方法需要创建栈帧;字节码指令需要基于栈帧中的操作数栈及局部变量表运行……所以,最重要的前置知识是内存模型

关于内存模型,这篇文章我就不展开讲了。如果你觉得学得不够扎实,或者我上面讲得这些你好像不是很熟悉,可以看我之前讲过的JVM底层原理之内存模型。因为我的文章是全网发,有的平台不允许发链接及二维码,你可以关注我的公众号【硬核子牙】回复【Hotspot书】获取。

手写JVM框架输出hello world,深入理解内存模型就够了吗?当然!不够!还有字节码指令。我直接拿出字节码指令告诉你它做了什么什么你肯定没概念对吧,那我手动模拟程序的运行让你GET到学习字节码指令的感觉。


手动模拟程序运行


贴下上面的Java程序对应的字节码指令

在这里插入图片描述
JVM在运行main方法的字节码指令前,会先构建运行环境。这个运行环境指:创建虚拟机栈、创建栈帧、根据常量池中提取的信息找到main方法对应的C++对象、从C++对象拿到操作数栈及局部变量表的尺寸来创建操作数栈及局部变量表……
在这里插入图片描述
环境构建好后就可以运行程序了,那每个字节码指令做了什么呢:
1、getstatic:获取静态属性。这里是获取System.out对象
2、ldc:将字符串的内存地址压入栈顶。这里是将hello word对应的内存地址压入操作数栈的栈顶
3、invokevirtual:执行方法。这里是执行println方法
4、return:返回void。这里我们写JVM需要pop出main方法对应的栈帧,释放虚拟机栈,释放内存


实现细节

上面讲了JVM运行Java程序的七个步骤,这部分我就拿我自己手写的JVM代码带大家看下细节


一、实现步骤2、3、4

在这里插入图片描述
代码有注释,我就不展开讲了。这里面有个代码有小伙伴问过我,就是为什么要创建线程?的确,我们目前实现的JVM是单线程版本的,压根不需要引入线程,我为什么要这样做呢?一、与Hotspot源码尽量保持一致。因为我们手写JVM的目的之一是为了更好的研究Hotspot源码;二、保持向后兼容。如果我不通过线程管理虚拟机栈,我得通过全局变量来管理,那我后面想将单线程的JVM升级为多线程的,这块我要做大改,属于项目重构,那为何不在开发之初就做好这个扩展呢?


二、实现步骤5

在这里插入图片描述
代码有注释,就不展开讲了


三、实现步骤6

在这里插入图片描述
我实现的是字节码解释器,运行效率不高,但是便于理解。JVM中目前在用的是模板解释器。什么?为什么不实现模板解释器?不是我不能教,是我没法教,模板解释器本质上是硬编码编织技术。以我对大家水平的了解,教这个属于劝退。但是我也不是完全放弃教这块了,但是可能要到手写JVM小班的五六期,等大家的基础补上来了。如果你不了解我说的,可以看我的JVM底层原理第十讲,我详细讲了模板解释器的底层实现原理。


四、实现步骤7

在这里插入图片描述
代码有注释,就不展开讲了


专栏目录


1、特别篇:学习完整版手写JVM的意义

2、开篇:学这套专栏课程的意义

3、实现字节码文件解析器


结语


没有人天赋异禀,这个世界其实很公平,它会残酷地惩罚那些不思进取不图改变的人,也会悄悄犒赏那些坚持努力奋斗的人。共勉。

我是子牙老师,下篇文章见。想交朋友?那就加我微信撒(jvm-ziya)。


### 如何在 Windows 系统中安装 PythonQt Designer 并配置环境 #### 安装 PyQt6 和 Qt Designer 为了在 Windows 上使用 Qt Designer,可以通过 `pip` 命令安装最新的 PyQt6 模块。PyQt6 是一个用于创建图形用户界面 (GUI) 应用程序的工具包,并附带了 Qt Designer 工具。 运行以下命令可以完成 PyQt6 及其相关组件的安装: ```bash pip install pyqt6-tools ``` 此命令会自动下载并安装必要的依赖项,其中包括 Qt Designer[^1]。 #### 配置路径以便访问 Qt Designer 安装完成后,通常可以在以下目录找到 Qt Designer 文件(具体位置取决于 Python 解释器的位置): - **对于标准安装**:`C:\Users\<用户名>\AppData\Local\Programs\Python\<版本号>\Lib\site-packages\pyqt6_tools` - 或者通过脚本启动:`python -m pyqt6_designer`. 如果希望直接从文件资源管理器或桌面快捷方式打开 Qt Designer,则需将其可执行文件所在路径添加到系统的环境变量 PATH 中。操作方法如下: 1. 打开控制面板 -> 系统和安全 -> 系统 -> 高级系统设置。 2. 单击“环境变量”,在“系统变量”部分找到名为 “Path”的条目并编辑它。 3. 添加上述提到的设计工具所在的完整路径至列表末尾。 这样处理之后,在任意 CMD 终端窗口输入 designer.exe 就能调用该应用程序。 #### 测试安装成功与否 验证是否正确设置了所有内容的一个简单办法就是尝试加载设计模式本身或者利用 PyQT 创建一个小项目来看看能否正常渲染 UI 元素。下面给出一段简单的例子展示如何载入由设计师保存下来的 .ui 文件并通过 python 运行起来: ```python from PyQt6 import uic import sys from PyQt6.QtWidgets import QApplication, QMainWindow class MyUI(QMainWindow): def __init__(self): super(MyUI,self).__init__() # 加载 ui 文件 uic.loadUi('your_ui_file.ui', self) if __name__ == '__main__': app = QApplication(sys.argv) window = MyUI() window.show() try: sys.exit(app.exec()) except SystemExit: pass ``` 以上代码片段假设存在一个叫做 'your_ui_file.ui' 的文件位于当前工作目录下,它是之前通过 Qt Designer 构建出来的界面布局定义文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值