【用Golang实现JVM第一篇】知识准备&前言

Gin+MySQL+Nginx裸机部署防坑指南:从零到生产上线 Web服务部署本质上是HTTP服务器、数据库与反向代理三者的协同工程。理解其底层原理——如Nginx proxy_pass路径重写机制、MySQL绑定地址与权限隔离策略、Go静态编译对libc的规避逻辑——是保障服务稳定的核心。这类组合部署不仅决定API可用性与安全性,更直接影响系统可观测性、升级弹性与审计合规性。典型应用场景包括政务/金融类物理机环境、资源受限边缘节点,以及需快速验证架构可行性的MVP项目。本文聚焦Linux原生环境下的Gin框架、MySQL数据库与Nginx反向代理三件套协同部署,覆盖安 阅读详情

学习JVM最好的方法,就是实现它,没有之一。

对JVM感兴趣的朋友可能会去主动寻找讲解JVM的书,比如《深入理解JVM》、《Java虚拟机规范》、《虚拟机的设计与实现》,但是这些书都是定性讲解,多数人看过以后对不少概念还是会很模糊,其根本原因就是我们无法只根据定义在脑袋里想象出具体用代码应该怎么实现,就会有一种空中楼阁的感觉。既然虚拟机规范都是公开的,为什么我们不尝试着去实现一个能跑就行的JVM呢?

方法论:将复杂问题化解为简单问题的集合

国外有一本著名的操作系统教材,叫作《Operating Systems: Three Easy Pieces》,读过的朋友一定会对内容的通俗易懂印象深刻,因为作者总是先从一种最简单的情况入手,然后逐步考虑更多的情况,最后扩展到实际问题。Oracle的Hotspot JVM实现是极其复杂的,如果打个比喻的话,我认为可以类比成美国已经退役的航天飞机,都是巨型工程。因此仅凭一己之力想实现完整JVM是很难的,必须将复杂的问题简化,然后各个击破。 比如,垃圾回收可以直接利用Golang自身回收机制,线程可以映射到golang的协程,native方法可以用开发语言直接实现,可以先不实现类,可以先不调用方法等等。当把最简单的零件实现以后,再拼凑起来实现更复杂的功能。这样一来,我们可以把实现JVM这个艰巨的任务分解成以下步骤:

  • 从classpath中读取class文件

  • 解析class文件

  • 实现解释器

其中解释器的实现可以根据字节码含义的复杂程度循序渐进的去做:

  • Mock一下System.out.println()方法(非常重要)

  • 操作数入栈、出栈、本地变量表读写、PC(程序计数器)跳转等基本指令

  • 基本的数学运算指令

  • static方法调用指令(invokestatic)

  • 数组、对象的创建指令(new, newarray)

  • 继承、接口、方法重载、方法重写等特性(invokespecial, invokevirtual)

  • 实现native方法、线程、GC等高级特性

我们习以为常的输出调用System.out.println()看似简单,但从JVM的角度来看却是巨复杂。这里我们可以特殊处理一下,比如Java中写一个native的print()方法,解释器遇到这个方法后就直接调用go的fmt.Printf() 函数输出即可。这一点很重要,因为输出计算结果是实现JVM的一个重要里程碑,如果过早的陷入System.out.println()的复杂度中的话就会很容易被劝退,而且前期在这里折腾时间挫败感会很强,也没啥意义,后续实现了对象创建、方法调用以后,System.out.println()自然就实现了。当我们把所有的字节码(200多个)都实现以后,JVM就真的实现了。别管什么性能好坏,先跑起来。其实只要实现基本的数学运算和数组,就能用自己的山寨JVM解leetcode了。

此外,在解释字节码的时候千万不要照着字节码指令表从头到尾一条条实现,更好的方法是自己写一段简单的Java代码,编译以后用JDK自带的javap -verbose XXXX来分析指令,然后看哪条没实现,就专门去实现哪条。Java代码要从易到难,开始先简单的定义一个变量加加减减,然后增加if判断,for循环,static方法,最后再new新对象,调用对象方法等等,循序渐进。这样就能给JVM这个大工程增加很多可衡量的里程碑,防止一开始就实现类导致掉进无穷的大坑中被劝退。

知识准备

实现一个能跑的JVM并不难,只要愿意查资料,一定能写出来,但是想要达到或接近Hotsport性能就很难了。这里我们的目标是用golang实现一个能跑的JVM,因此要熟练掌握至少一门编程语言, 然后查资料详细了解class文件结构。这方面网文很多,但都不够系统,最好从书里找,推荐《深入理解JVM》,这本书里面对class结构的介绍就已经足够让你完成解析class文件的任务了。

解析完class以后,我们还要构建一个能跑字节码的"环境",比如方法栈,操作数栈,本地变量表,程序计数器等,这些在书里都有详细的说明,也可以根据描述自己实现出来。

字节码的解释。这里推荐直接看JVM规范,Oracle有在线文档:https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5 ,可以直接看字节码指令这一部分,需要什么就直接把它当成一个字典去查。随着解释的字节码越来越多,你会发现需要实现的东西也会变多,根据指令需求去实现缺的东西就可以了。

其实JVM规范给JVM的具体实现留下了很大的空间,只要能准确实现指令本身的语义,不管用什么方法都是可以的,千万不要纠结于性能,过早优化是万恶之源。

最后,我已经用golang做了一个实现了条件判断、循环、静态or对象方法调用的Mini-JVM, 后期会持续开发,目标是有一天能够完全实现一个JVM,有兴趣可以关注一下: https://github.com/wanghongfei/mini-jvm

Java在安全事件响应中的五大实战武器:从实时处理到内存取证 在系统安全领域,事件响应(Incident Response)是保障业务连续性的关键环节,其核心在于快速检测、分析和遏制威胁。传统人工处理海量日志的方式效率低下,而自动化与实时处理技术成为提升响应效率的工程实践基石。Java凭借其稳定的JVM生态、强大的并发处理能力以及对复杂数据流的原生支持,在企业级安全事件响应中扮演着重要角色。其技术价值体现在能够无缝集成Kafka、Flink等大数据组件,构建端到端的实时事件处理管道,实现复杂事件的关联分析与自动化决策。在应用场景上,Java不仅能用于深度分析攻击载荷( 阅读详情

相关推荐

VS Code配置Java开发环境:从JDK安装到项目调试全攻略

Java开发环境配置是每个开发者入门的必经之路,其核心在于理解JDK、构建工具与编辑器之间的协同原理。JDK作为Java程序的运行基石,其版本选择与环境变量配置直接影响项目的编译与执行;而构建工具如Maven则通过依赖管理和项目标准化,提升了开发效率。在轻量化编辑器成为趋势的今天,VS Code凭借其强大的扩展生态,为Java开发提供了高度可定制化的解决方案。通过安装Java扩展包,开发者可以获得代码补全、调试、测试等核心功能,实现与传统IDE相近的开发体验。针对实际开发中常见的内存不足、版本冲突等问题,合

weixin_30323631的博客 401

记我的一次JVM监控

环境: jdk1.8 ubuntu 16.04先看图 上面两张图片是jconsole监控界面,程序已运行超过12小时。先说下程序吧:主要是用来网站二维码图片的预热,生成300*300的大小的二维码,并且调用ImageMagick将图片压缩未90大小。 public static void generate(List<String> list){ list.parallelStre

乄浅醉的专栏 745

Go的JVM实现-Golang开发

gojvm gojvm是Go的JVM实现。 它可以解释并运行JVM字节码文件。 当前,它仅支持&ldquo; hello world&rdquo;和算术加法。 用法Hello world HelloWorld.java公共类gojvm gojvm是Go的JVM实现。 它可以解释并运行JVM字节码文件。 当前,它仅支持&ldquo; hello world&rdquo;和算术加法。 用法Hello world HelloWorld.java公共类HelloWorld {public static void main(String [] args){System.out.println(&ldquo; H​​ello world&rdquo;); $ cat HelloWorld.class | 去运行main.go(git)-[master](p9)Hello world Arithm

Go语言实现 JVM(一)命令行工具

零、写在前面 JVM 的学习是每一个致力于 JAVA 语言的程序员一段最特殊的经历,至少说对于博主来说是这样的,有时候总是前脚看了,后脚就忘了。要是自己写一个 JVM,大概就很难忘了吧。带着这样的想法,博主找到一本《自己动手写 Java 虚拟机》的书,好了,话不多说,开整。 ps:博主已经把代码托管到了 GitHub 上,下面是地址 https://github.com/Mor1aty/golan...

Mor1aty的博客 2294

go语言编写jvm虚拟机

使用go语言编写的简单的jvm虚拟机,使用go语言编写的简单的jvm虚拟机

mysql数据目录迁移后表不存在_mysql 直接从date 文件夹备份表,还原数据库之后提示 table doesn`t exist的原因和解决方法...

补充:正常情况下,建议数据库备份最好用工具进行备份,通过拷贝数据库表进行数据迁移,不同的环境会出现各种不同的意外问题。背景:今天在整理一个网站的时候,操作系统由于系统自动更新导致一直出现系统蓝屏死机,唉,悲剧了,于是重新安装了系统 windows server 2008 enterprise 32bit。详情:系统安装完成后,重新配置之前那个网站,appache服务配好之后,再配置数据的时候是这样...

weixin_39628271的博客 2671

Golang实现JAVA虚拟机-运行时数据区

Java虚拟机可以操作两类数据:基本类型(primitive type)和引用类型(reference type)。基本类型的变量存放的就是数据本身布尔类型(boolean type)数字类型 (numeric type)整数类型(integral type)浮点数类型(floating-point type)。引用类型的变量存放的是对象引用,真正的对象数据是在堆里分配的。类类型:指向类实例接口类型:用指向实现了该接口的类或数组实例数组类型: 指向数组实例null。

sdgfafg_25的博客 1153

【Excel VBA 编程】批量核对两张表格数据,行和列显示顺序均被打乱

利用数据字典在 Excel 中进行表格数据的核对,该表格含有多行多列,并且行和列顺序是打乱的,批量核对数据后将差异输出

wei1019的专栏 1291

[Golang实现JVM第三篇] 解释器雏形

在上一篇中我们已经完成了class文件的解析工作,虽然没有解析所有的属性,但是已经足够支持一些基本的算法题Java代码编译生成的class文件了。有了这一步,日后如果遇到新的特性需要支持,只需缺哪补哪,补上对应属性的解析逻辑就可以了。下一步就是实现一个基本的执行引擎,即解释器,并且支持基本的栈操作相关的指令,比如iconst_x, istore_x, bipush等。 基于栈的指令集和基于寄存器的指令集 JVM字节码是一套基于栈的指令集,也就是说操作数栈是一切计算的基本容器,大部分指令都是围绕着操作数栈展开

停止更新 608

洛谷 P5736 【深基7.例2】质数筛

题目描述 输入 n(n\le100)n(n≤100) 个不大于 100000 的整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。 输入格式 无 输出格式 无 输入输出样例 输入 #1 复制 5 3 4 5 6 7 输出 #1 复制 3 5 7 板子题,使用一下线性筛 #include &lt;iostream&gt; #include &lt;cstdio&gt; #include &lt;cstring&gt; #include &lt;algorithm&gt; using n

qq_37978559的博客 1117

一个三极管和稳压管构成的简易稳压电源

一、对电压精度要求不高的场所可以使用本文中所述的简易稳压电源(电流变化引起 的基极-发射极的压降 变化 对输出电压来说可以容忍)二、根据负载实际需求选择三极管,不同的三极管集电极电流不同,电流放大倍数不同(1、尽量选择负载电流(iC 或 iE)上限时,hFE仍然比较理想的三极管,2、一般三极管对基极电流没有限制,可以适当调整基极电流以获得所需输出电流)

五花带点肉 1万+

不懂如何实现JVM可观测?技术大咖优秀实践分享来啦

前置条件 账号注册 前往官方网站https://www.dataflux.cn/注册账号,使用已注册的账号/密码登录。 安装 Datakit 获取命令 点击 [集成] 模块, [DataKit],根据您的操作系统和系统类型选择合适的安装命令。 执行安装 复制 Datakit 安装命令在需要被监控的服务器上直接运行。 安装目录 /usr/local/datakit/ 日志目录 /var/log/datakit/ 主配置文件 /usr/local/datakit/conf.d/da..

观测云的博客 678

基于STM32的宠物智能照护嵌入式系统设计

嵌入式系统是实现物联网终端设备本地化感知、决策与执行的核心技术载体,其关键在于多传感器融合、低功耗执行控制与轻量级云边协同。本文围绕环境监测(温湿度、烟雾、余粮)、机电执行(步进电机食盘、继电器风扇)和可靠通信(MQTT+ESP8266)三大技术主线,深入解析STM32F103在资源约束下的外设调度策略、ADC采样抗干扰设计、DHT11时序精准控制及HX711称重滤波算法等工程实践要点。系统强调本地闭环优先原则,确保离线基础功能可用,同时通过阿里云IoT平台实现远程监控与告警联动,为中小型智能硬件项目提供可

weixin_29155599的博客 291

Go实现LLM推理网关:SSE流式转发与级联取消实战解析

在构建高并发AI服务时,如何统一管理大模型API调用成为工程化落地的重要课题。基于HTTP协议的SSE(Server-Sent Events)技术,为模型输出的实时流式传输提供了轻量级解决方案,但其转发过程中的数据缓冲、连接保持与错误传播机制,往往成为系统稳定性的潜在瓶颈。与此同时,Go语言的Context机制为请求生命周期管理提供了优雅的取消信号传递能力,能够有效实现级联取消,避免因客户端中断导致的上游资源浪费。结合背压控制策略,网关能够在高负载下保护下游服务而不牺牲整体吞吐。从统一鉴权、流量治理到多模型

weixin_31102231的博客 226

100天精通Python(可视化篇)——第109天:Pyecharts绘制各种常用地图(参数说明+代码实战)

100天精通Python(可视化篇)——第109天:Pyecharts绘制各种常用地图(参数说明+代码实战)

努力让自己发光,对的人才能迎着光而来 8万+

液态神经网络(Liquid Neural Networks)从线虫大脑到下一代 AI

液态神经网络(Liquid Neural Networks,LNN)是一类具有动态内部结构的神经网络,其灵感来源于生物神经系统,尤其是大脑中神经元如何以复杂、非线性的方式响应外部刺激。与传统神经网络不同,液态神经网络的每个神经元在处理输入时,不再是静态线性或非线性变换,而是基于一个微分方程模型进行响应。这种建模方式使神经元的行为具有时间连续性和动态适应性。换句话说,它不仅“记住”过去的信息,还能根据当前环境实时调整自身的动态特性,这对于感知、决策、预测等任务都非常关键。

hello.reader 7406

Java工程师的成长路线图是什么?

大家好,我是极客时间《Java核心技术36讲》作者、前Oracle首席工程师杨晓峰,今天,我想借自己的经历,跟大家分享Java工程师从新手进阶到专家的路线图是什么?有哪些阶段?每一阶段又该掌握哪些技能?\n我经常能听到一些同学困惑,“面试造火箭,天天拧螺丝”,每天进行重复的业务开发,似乎自己的能力被日常工作限制,无法突破提高自己的能力水平。\n我想说,难道懂得如何造火箭,还能没有实际价值吗?它的价...

nostrud ipsum6 698

EMC诊断技术及电磁兼容理论设计

本文深入探讨了EMC诊断技术,重点在于滤波篇,详细讲解了EMI滤波器的设计、选型、测试及应用注意事项。内容涵盖噪声限值法规、滤波器的法规依据、插入损耗测试以及滤波电容的高频特性。同时,还阐述了噪声源的近场与远场特性,如何快速定位和抑制噪声。通过实例分析,提供了滤波器件和辐射噪声抑制器件的选型策略。

让你爱上电路设计 2161

《jdk8u源码分析》6.CreateExecutionEnvironment

src/windows/bin/java_md.c::CreateExecutionEnvironment /* * */ void CreateExecutionEnvironment(int *pargc, char ***pargv, char *jrepath, jint so_jrepath, ...

johnjoe's blog 522

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Minecraft服务器无响应故障排查:从死寂状态到性能优化的完整指南

Java虚拟机(JVM)作为Minecraft服务器的运行环境,其内存管理和线程调度机制直接影响服务稳定性。通过JVM参数调优和GC垃圾回收策略优化,可以有效提升服务器性能。在游戏服务器运维实践中,端口监听状态监控和资源占用分析是基础排查手段,而线程转储分析则能深入定位死锁和性能瓶颈问题。针对Minecraft服务器常见的无响应故障,需要结合系统监控工具和Java专用诊断命令,建立从网络连通性测试到内存泄漏检测的全链路排查体系。本文以服务器死寂状态为切入点,详细介绍了CPU占满、内存不足等资源耗尽型问题的解

weixin_34279246的博客 343

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

windows 7 64位编译安装pylucene记录

自己编译永远是一件很烦的事情,不常用,需要时网上找教程,但都是过时的信息,极少遇到能完全套用的。因此记录一下自己这次编译pylucene的经过。过程可能记录不详,但是遇到的大坑,和具体的思考过程应该都记录好。 主要参考和复制来源:https://www.aliyun.com/jiaocheng/774024.html?spm=5176.100033.2.10.FpxaV8 1、准备:  py...

freedomxu的专栏 1214

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

C++是如何运行C#/.Net的?

前言C#这门语言是运行在.Net平台上面的。那么.Net平台是依靠什么运行的呢?没错就是C++。严格来说是类C的C++。本篇来看下。概括1.引申知乎上有个提问:C#和C++语句有区别吗?当时回答的是:C++严格来说是C#的干爹那么反过来,C#是C++的干儿子为什么这么说呢?C#的运行时CLR的小型主机CoreRun超过90%类C的C++。那么C#的亲爹是谁呢?自然是微软了2.托管与非托管实际上大部...

dotNET跨平台 496

Netflix是如何针对云构建和部署代码的

2008年秋季,Netflix遭遇了一次严重的数据库故障,连续3天无法向成员寄送DVD,从那时起,他们决定向云迁移。今年2月,Netflix宣布完成了向云的迁移。\\而与之相应的是,Netflix的开发工作也要针对上云做很多工作。那么,Netflix的代码在部署到云上之前,是如何构建的呢?\\Netflix的三位工程师Ed Bukoski、Brian Moyles和Mike McGarr撰文介绍了...

weixin_34044273的博客 86

Docker - 与GitLab CI结合,实现代码提交自动构建镜像

选择 GitLab CI 并非出于偏好,而是源于其架构一致性与开箱即用的安全边界✅同源存储:代码仓库、CI 配置、制品仓库(Container Registry)、环境变量、密钥管理全部内置于同一平台,权限模型统一(Project → Group → Instance),避免跨系统凭证同步风险;✅Runner 即服务:支持共享 Runner(Shared Runner)与项目专属 Runner(Specific Runner),可轻松对接自建 Kubernetes 集群或裸金属节点,资源调度透明可控;

千淘万漉虽辛苦,吹尽狂沙始到金 5855
上一篇: Go使用chromedp库操作headless-chrome爬取"JS画出来的"网站
下一篇: [Golang实现JVM第二篇]解析class文件是万里长征第一步
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值