自制Runtime:虚拟执行环境设计

Java虚拟机中获得Runtime实例的方法是什么?   Runtime类用于表示Java虚拟机运行时的状态,它用于封装Java虚拟机进程。每次使用“java”命令启动Java虚拟机时都会对应一个Runtime实例,并且只有一个实例,应用程序会通过该实例与其运行时的环境相连。应用程序不能创建自己的Runtime实例,若想在程序中获得一个Runtime实例,可以通过getRuntime()方法获取与之相关的Runtime对象,具体方式如下:   Runtime run = Runtime.getRuntime();   由于Runtime类封装了Java虚拟 阅读详情

编译器前端基本设计已经完成(详见我的自制编译器系列博文),但在考虑编译器后端之前,首先要考虑代码的运行环境,因此考虑再三我便把制作Runtime的过程写成博文,记录从中所学到的知识。

Runtime的设计以JVM为原型,加以部分的简化来去掉复杂的功能,并使得简单的Runtime可以在不多的代码行数内加以实现。

总的来说我们的Runtime需要实现以下几个功能:

1、运行特定的程序指令

2、以控制台的方式进行输出

3、可检查出运行时错误(如数组越界,空指针错误等)

4、有垃圾收集机制


一、Runtime结构设计

(1)帧栈

因为运行时暂且不考虑多线程并发或伪并发,所以整个Runtime具有一个帧栈,帧栈中存放栈帧。帧栈用于函数调用,每个调用函数都有着自己独立的栈帧,并在调用时将此帧压栈,返回时将栈帧弹出。

一个栈帧具有以下结构:

1、方法信息

记录当前调用的方法的签名

2、IP

指令寄存器,记录下一条将要执行的指令的位置,根据此之前的方法信息和IP从静态方法区获取指令。值得注意的是,每个方法具有自己独享的IP,这样可以简化方法退出时的恢复现场的工作。

3、局部变量表

局部变量表存放局部变量的信息,非static调用时this指针压在变量表的第一个位置。如果局部变量是一个基本数据类型(char,int ,double),局部变量表存放局部变量的值,否则存放一个对象的句柄。同时函数调用时参数均是通过局部变量表进行传递的。

4、操作数栈

虚拟执行环境设计成基于栈的执行环境,因此每个方法都有自己的操作数栈,方法调用时给其栈分配空间,返回时释放栈的空间。值得注意的是,每个方法都有专属于自己的栈所带来的好处是简化了方法进入和退出时的清理堆栈的工作,但需要额外的机制来进行返回值的传递。在设计中我们首先通过帧栈找到其调用者的栈帧,然后将返回值压入其调用者的操作数栈中。


(2)堆

所有对象的数据部分存储在堆上,一个堆可以理解为一段连续的地址空间,并且当堆的大小不够时可以进行动态的扩展。垃圾收集工作只在堆上进行。


(3)对象表

一个对象表由若干表项构成,一个表项为一个三元组,包括对象句柄、堆中位置及额外信息。使用对象表来存储程序运行过程中所有的对象的信息。

所谓对象句柄为一个32为整数,是某一个对象在Runtime的唯一标识,指令中所有对对象的操作均通过对象句柄来完成。

堆中位置描述一个对象在堆中的存储位置,并通过方法区类的相应接口来解析出该对象中的数据。此位置不固定,每次GC之后堆中位置或许会发生改变。

信息包含该对象的基本信息,包括但不仅限于一个指向该对象从属类的指针、是否是静态变量标识、数组长度、访问权限等。


(4)静态方法区

Runtime加载类之后将类的信息存储于静态方法区,这其中包括类的字段、类的方法签名、类的方法的指令序列。

堆中的内容将通过静态方法去类字段的内存布局来解析,同时执行引擎通过查找特定类的方法指令序列来执行指令。


二、类文件格式设计

为了使解析、阅读方便,在类文件格式设计中,信息以“行”的形式进行存放,每行之间通过\r\n进行分割。

类文件开头第一行:类名

第二行:字段数n

接下来的n行为字段

字段格式如下:

开头是一个0--4的整数,其中第一位代表是否是public,第二位代表是否是static;其后是字段类型,最后是字段名。三个信息以空格进行分割。

接下来一行是方法数m

接下来有m个方法体。

每个方法体开头为0--4的整数,其中第一位代表是否是public,第二位代表是否是static。接着是返回值类型,之后是方法名,之后是参数数量p,之后是p个参数类型。各信息之间以空格进行分割。

之后一行为{ ,代表方法的指令码开始。

之后跟若干行指令,指令以如下格式存放:

地址:指令码  操作数1,操作数2

其中地址为从1开始递增的整数,指令码为0--256的整数,详细参加之后定义,操作数可为立即数、字符串或没有操作数。

之后跟若干行为长量表,格式为#i  const,目前主要用来存储常量字符串。

例如: #0  hello,world

            #1  Runtime 

之类的 

三、指令码设计

基本参考Java字节码,并在此基础上加以简化。

字节码                助记符和指令格式             含义

0x00                      nop                                什么都不做

0x01                      iconst  X                         整形常量X压入堆栈

0x02                      dconst  X                        浮点常量压入堆栈

0x03                      load  X                            将本地变量表的第X位置的值压入堆栈

0x04                      aload                      将栈顶元素所指向的数组的第X个元素压入堆栈,X是栈自顶向下第二个元素

0x05                      store X                            将栈顶元素存入本地变量表的X位置

0x06                      astore   Y                将栈顶元素指向的数组的第X个元素存入本地变量表的Y位置,X是栈自顶向下第二个元素

0x07                      iadd                                 将栈顶两元素作为int相加并将结果压入栈

0x08                      isub                                 将栈顶两元素作为int相减并将结果压入堆栈

0x09                      imul                                  将栈顶两元素作为int相乘并将结果压入堆栈

0x0A                      idiv                                    将栈顶两元素作为int相除并将结果压入堆栈

0x0B                      dadd                                 将栈顶两元素作为double相加并将结果压入栈

0x0C                     dsub                                 将栈顶两元素作为double相减并将结果压入堆栈

0x0D                      dmul                                  将栈顶两元素作为double相乘并将结果压入堆栈

0x0E                      ddiv                                    将栈顶两元素作为double相除并将结果压入堆栈

0x0F                      ishl                                   将栈顶元素作为int左移X位并将结果压入堆栈,X是第二个元素

0x10                      ishr                                   将栈顶元素作为int右移X位并将结果压入堆栈,X是第二个元素

0x11                      iand                                  栈顶两元素按位与,结果压入堆栈

0x12                      ior                                      栈顶两元素按位或,结果压入堆栈

0x13                      ixor                                      栈顶两元素按位异或,结果压入堆栈

0x14                      i2d                                     栈顶int转double ,结果压入堆栈

0x15                      d2i                                     栈顶double转int,结果压入堆栈

0x16                      icmp                                   栈顶两元素当作int比较,结果压入堆栈(-1,0,1)

0x17                      dcmp                                  栈顶两元素作为double比较,结果压入堆栈

0x18                      ifz  X                                   如果栈顶元素是0,则跳转到X处执行

0x19                      ret                                      函数返回

0x1A                      invoke  X                            调用栈顶对象的非静态函数。

0x1B                      invokestatic X                     调用静态函数,X为函数全限定名,如Class.function

0x1C                      new                                    新建对象,并将对象句柄压入堆栈

0x1D                      newarray X                           新建类型X数组,并将数组句柄压入堆栈

0x1E                      arraylength                          将栈顶指向数组的长度压入堆栈

0x1F                      putfield   X                            将栈顶元素赋值给栈第二个元素指定对象的X域中

0x20                      getfield  X                             栈顶元素所指向的对象的X域的值压入堆栈

0x21                      putstatic X                            栈顶元素赋值给X

0x22                      getstatic X                             X所指向的静态变量压入堆栈

0x23                      pop                                      栈顶元素弹出

0x24                      NAND                                    栈顶元素取非

0x25                      ldc X                                     将常量表下标为X的字符串对象句柄压栈

0x26                      astore_1                               栈顶元素赋值给栈第二个元素指向的数组的下标为栈第三个元素的值 

Agent Runtime 本质:事件日志驱动的可靠执行环境 Agent runtime 是支撑大模型智能体稳定运行的底层基础设施,其核心原理在于将状态管理、安全执行与可观测性从模型推理中解耦。技术价值体现在通过 Session-as-Event-Log 实现可追溯、可重放、可审计的确定性执行,结合沙箱隔离与凭证托管保障生产级安全性。典型应用场景包括客服对话状态恢复、跨系统数据同步断点续传、金融风控指令隔离等。随着 AWS AgentCore 等云厂商推动 runtime 零价化,工程重心正加速上移至 trace store、policy engine 和垂直 age 阅读详情

相关推荐

EPLAN 2025安装故障前置推演:虚拟化环境校验与Runtime VM部署

EPLAN Electric P8 2025不再依赖本地数据库,而是基于Linux虚拟机(Runtime VM)构建微服务架构,本质是将电气设计软件升级为云原生式部署模式。其核心原理在于通过VMware/VirtualBox运行预配置Ubuntu容器,承载许可证服务、符号索引与图纸渲染等关键组件。这一转变带来显著技术价值:多用户协同一致性提升、符号搜索性能跃升4倍、EDZ设备导入稳定性达100%。典型应用场景包括全国大学生电子设计竞赛备赛、工业自动化项目快速原型开发等对环境确定性要求极高的工程实践。本文聚焦

过客阵营 -- 简单的就要最简单 441

字节码执行

#虚拟机之字节码执行 ##1、字节码执行从栈帧说起 栈帧就是Java虚拟机里执行由字节码编译成的机器代码的地方,包含两个结构:局部变量表和操作栈。 局部变量表时一组变量值的存储空间,代码里用到的变量值都会放到局部变量表中,其最小单位为slot,每一个slot都是可复用的,而没被复用或清空的slot对象仍存在关联时,该slot不会被GC回收。 实例方法中第一个即第0位索引slot是“this”参...

ChuckLin的博客 871

Android-ShellDroidAndroidApp多开虚拟运行环境

ShellDroid:Android App 多开虚拟运行环境

【ai_agent】从零写一个agent框架(二)如何让一个workflow/agent跑起来,runtime模块设计

上篇文章我们大致演示了一下ai_agent的食用方法。这里我们做一下核心模块runtime的设计和实现。一个agent也好,workflow也好,他们单个实现起来并不复杂,困难的是如何将他们有机的组合起来,能够按照一定的逻辑流转起来。并且能够层层嵌套,能力无限。现实中应用肯定不局限于这几种情况,但通过一定的流程编辑基本都可以解决,只是复杂性会比较高。

python1234_的博客 1140

从零配置ORB-SLAM3:TUM-VI数据集yaml文件参数调优指南

本文深入解析了ORB-SLAM3在TUM-VI数据集上的yaml配置文件参数调优方法。针对双目惯性模式,详细拆解了相机标定、IMU噪声模型和ORB特征提取三大模块的关键参数,解释了其原理与影响,并通过实战案例展示了如何通过调整特征点数量、FAST阈值及IMU噪声参数,有效提升系统在低纹理环境下的鲁棒性和轨迹精度。

weixin_29071809的博客 151

支付系统保证可靠性的秘诀 ----- 订单的补偿和补单

文章目录WHAT? 前言WHY? 为什么要用多级缓存?HOW 怎么做?方案 版本1:数据库存储专线配置通过优先级进行动态上下线方案 版本1 劣势:方案 版本2 :本地缓存替代数据库方案 版本2 劣势:方案 版本3:分布式缓存做自动补偿方案 版本3 总结:Where 分布式多级缓存还能用在哪些地方?总结 WHAT? 前言 刚入职场的时候觉得支付宝等第三方支付系统好强大,要保证这么多的交易不能错,也不能重复还要保证正确的扣钱,直到后面接触订单系统以及第三方支付公司的核心交易系统后才真正窥探到了支付系统的核心

boboaisisi的专栏 3534

什么是Runtime?平时项目有用到过吗?

我们在面试中经常会被问到这些问题,到底怎么回答比较合适? 这样我们先去看一下我们平时项目中用到的Runtime,等下我们再来概括上面的问题的答案.我们肯定是用Runtime提供的API去做一些事情. 我们肯定是多多少少有接触Runtime,如果面试官问你,你肯定回答用过,不然说明你对Runtime一点都不了解.这样对你的印象就大打折扣了. 现在我就列一些我们可能用到的API(注意只是部分,不是所有). Runtime类相关的API Runtime成员变量相关的API Runtime属性相

Lucky_Deng的博客 690

GD32单片机引脚复用指南:如何让JTAG接口的PA15/PB3发挥第二功能?

本文详细介绍了GD32F103Cx系列单片机如何通过AFIO模块进行引脚复用,特别是将默认用于JTAG调试接口的PA15、PB3等引脚释放为普通IO或复用功能引脚。文章从原理出发,结合代码实践,讲解了如何配置调试端口重映射,将JTAG引脚安全地转换为GPIO或定时器通道,并提供了常见问题排查与最佳实践,帮助开发者高效利用有限的引脚资源。

nept的博客 807

iOS中Runtime的设计

本文引用资料: juejin.im/post/58f833… draveness.me/load www.jianshu.com/u/2de707c93… zhuanlan.zhihu.com/p/26379488 juejin.im/post/58f830… segmentfault.com/a/119000000… tech.meituan.com/2015/08/12/… 一、Runtime...

weixin_34326558的博客 181

Goose开源程序本地机上 AI 代理,能够从头到尾自动执行复杂的开发任务。Goose 不仅可以提供代码建议,还可以自主构建整个项目、编写和执行代码、调试故障、编排工作流程以及与外部 API 交互

Goose开源程序 是您的本机上 AI 代理,能够从头到尾自动执行复杂的开发任务。Goose 不仅可以提供代码建议,还可以自主构建整个项目、编写和执行代码、调试故障、编排工作流程以及与外部 API 交互。无论您是在构建想法原型、优化现有代码,还是管理复杂的工程管道,goose 都能适应您的工作流程并精确执行任务。

struggle2025的博客 2041

uni-app项目中引入Vant UI组件库(完美避坑!!!)纯净版

uni-app项目中引入Vant UI组件库(纯净版--无uni-ui)

Wzmlzrr的博客 3万+

对付虚拟执行

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34311757的博客 109

【首份】2023年30米分辨率土地利用遥感监测数据

为了恢复和重建我国土地利用变化的现代过程,更好地预测、预报土地利用变化趋势,地球资源数据云以美国陆地卫星Landsat 遥感影像数据作为主信息源,结合Sentinel系列数据,通过人工目视解译和机器学习方法,建立了国家尺度1:10 万比例尺多时期土地利用/土地覆盖遥感监测数据库(CNLUCC)因早期Landsat数据时空覆盖缺失,1972-1977年合成第一期数据,1978-1985年合成第二期数据,1986年起每年度生成一期数据。投影:Albers正轴等面积双标准纬线圆锥投影南标准纬线:25°N。

地球资源数据云的官方博客 3669

Java Runtime 类详解:虚拟机运行环境的交互与控制

java.lang.Runtime类用于访问和控制 JVM 运行环境,采用单例模式,通过getRuntime()获取唯一实例。 其核心方法包括:exit()终止虚拟机;availableProcessors()获取 CPU 线程数;maxMemory()、totalMemory()、freeMemory()获取 JVM 内存信息;exec()执行系统命令;gc()触发垃圾回收。 实战中可结合系统命令实现交互功能,如猜数字游戏猜对后调用shutdown命令关机。使用时需注意权限、资源释放及跨平台差异。

Shabbt的博客 644

多仓智能订单路由与动态优化方案设计

现在有很多商家会有多个仓库,并分布在不同的城市中,当用户下单后会根据商品库存及订单信息将订单分配到对应的仓库进行发货,如就近原则,本期基于多仓库设计一套订单路由方案,包含核心逻辑、规则优先级和实施方案,适用于多仓协同的订单自动分配场景

14年产品经理老兵,想把自己的经验及总结分享给大家,只讲思路及实操,不讲废话 2476

25 - GRACE Mascon数据缺失月份数据插值

本篇基于文章的相关内容和文章公开的奇异谱分析(SSA)插值算法程序包,对grace Mascon数据种缺失的月份进行 插值 ,总结了使用程序包的相关过程,可以将该程序应用到其他数据处理插值计算中。

weixin_43339605的博客 1842

Java Runtime.getRuntime().exec 不执行

Java Runtime.getRuntime().exec 不执行 在linux服务器上用java调用脚本,直接写 Java Runtime.getRuntime().exec(“要执行的命令”)有时候发现并不能执行响应的命令。 原因 这是因为linux执行命令需要使用linux系统自带的sh工具,而java虚拟机有时候并不能获取到系统的环境变量,导致命令无法被执行 解决方法 在命令前加上 /b...

王者丶丿风范 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java调用Anaconda虚拟环境执行Python

前言 本文介绍Java如何调用在anaconda虚拟环境中如何执行python脚本。 注意: 1、python脚本必须都用的是绝对路径(可以拼接) 2、python脚本调用自定义的模块时要将模块路径添加到环境中。如果用sys.append(模块绝对路径),要每一个脚本都要添加项目所在的路径。 cmd命令行执行: 环境路径 空格 项目路径 用Runtime.getRuntime().exec() (特别提示:如果想用jython的话,请用python2写程序,jython不支持p...

baidu_33512336的博客 4519

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java中Runtime运行时环境机制总结

最近由于在编码中需要在java代码中执行linux命令,使用到了Runtime类的一些方法,也出现几个小bug,所以趁这个机会对Runtime也就是运行时环境这个类进行总结。 Runtime.getRuntime()能得到一个Runtime对象实例,也就是当前运行时环境实例,这个玩艺是什么东西?java中称为虚拟机的运行时环境,这个说法很抽象,我在网上百度了很久,没有确切的说法,我感觉这个Run

qq838642798的博客 2762

浅析鸿蒙(ark runtime)执行动态代码

出于安全考虑鸿蒙(ark runtime)在ts层面对动态执行代码作出了诸多限制,但是我们仍能通过napi / jsvm的方式达到动态执行代码的目的,尤其是napi,可在主vm环境中执行动态代码,并且能享受到方舟编译器所带来的性能优化。

Abinzhao 1843

Android Runtime虚拟机实例创建与全局状态初始化(11)

Android Runtime(ART)虚拟机实例的创建与全局状态初始化是Android系统运行的基石,其过程直接决定了Java应用程序能否在设备上稳定、高效地执行。从系统启动到每个应用进程的创建,ART虚拟机实例的正确初始化确保了内存管理、类加载、代码执行以及垃圾回收等核心功能的正常运转。全局状态的准确初始化不仅保障了单个应用的运行环境,还维护了整个系统中多个应用进程之间的资源隔离与协同工作,对于提升Android系统的稳定性、流畅度和安全性起着关键作用。

Android开发领域创作者 1525

【Java】Runtime

表示的是当前虚拟机的运行环境,而在我们的电脑当中,一个电脑只能有一个运行环境,所以说如果你创建了多个对象,它是没有实际意义的,因此Java就规定了,在Java代码中运行的时候有一个小细节,方法的下面有一个红色波浪线,其实是给了你一个提示:你调用这个方法有可能会出现一些问题,那么我该如何解决呢?上面的方法都是获取到运行对象里面的一些参数,在以后如果我们需要通过Java代码去监控虚拟机的内存,那么上面这几个方法就可以用上了。​ 当你的好基友点击中间三个按钮的时候就在N秒之后关机,不同的按钮N的值不一样。

qq_39921135的博客 1880

tiny11builder 保姆级指南:把官方 Windows 11 ISO 压缩成 tiny11.iso

tiny11builder 是一套 PowerShell 脚本,用 Windows 自带的 DISM 把官方 Windows 11 ISO 里的预装应用成批剔除、再重压回一张更小的 tiny11.iso。它不挑版本、语言或架构,适合老硬件装机、主力机减预装和批量铺虚拟机三种场景。 🧩 **出盘链路只靠微软自家工具**:DISM 负责挂载、删包、压缩,Windows ADK 里的 `oscdim

gitblog_00668的博客 820

Starship No Runtime Versions 预设详解:为容器与虚拟化环境隐藏语言运行时版本号

Starship 默认会在检测到语言项目时显示对应运行时的版本号,而在容器、虚拟化或需要频繁切换运行版本的工作环境中,这些版本信息往往毫无意义,反而徒增提示符噪音。本篇以 Starship 官方预设之一 "No Runtime Versions" 为主线,完整讲解它的作用、一条命令的启用方式、覆盖的 54 个运行时模块的完整 TOML 配置,并结合仓库源码剖析"隐藏版本号"背后的 format 变

gitblog_01084的博客 1066

Runtime详解,一文带你打通Java Runtime类及其相关知识。

本文将带你详细了解java Runtime类以及其相关知识点,帮你构建完整的知识体系,并且标注了作者在使用时遇到的一些坑。

koveerKV的博客 5931
上一篇: 自制编译器:语法分析器(二)
下一篇: 自制编译器:静态检查
ROger__Wong
博客等级 码龄14年 250粉丝 78原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值