如何理解 Rust 没有运行时(No Runtime)

文章目录

  • 0.前言
  • [1. 运行时(Runtime)通常指什么?](#1. 运行时(Runtime)通常指什么?)
  • [2. Rust 的"无运行时"到底指什么?](#2. Rust 的“无运行时”到底指什么?)
  • [3. 一个简单的对比](#3. 一个简单的对比)
  • [4. Rust 真的"零运行时"吗?](#4. Rust 真的“零运行时”吗?)
  • 5.总结
  • 参考文献

0.前言

Rust 核心卖点之一高性能的描述如下:

Rust is blazingly fast and memory-efficient: with no runtime or garbage collector, it can power performance-critical services, run on embedded devices, and easily integrate with other languages.

Rust 速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成。

Rust 没有运行时,这个确实容易让人困惑:一个程序没有"运行时",怎么跑起来的?

我们需要区分"运行时"在不同语境下的含义。

1. 运行时(Runtime)通常指什么?

在很多高级语言中,"运行时"是一个较大的、在程序启动前就必须准备好的环境。它通常包含:

  • 垃圾回收器:一个后台线程,自动管理内存。
  • Just-In-Time (JIT) 编译器:运行时将字节码编译为机器码。
  • 反射机制:在运行时检查和调用类型信息。
  • 线程调度器(对协程而言,如 Go 的 Goroutine 调度器)。
  • 标准库的"胶水"代码:连接程序与操作系统的部分。

例如:

  • Java : 启动一个 Java 程序,会先启动 Java 虚拟机(JVM) 。JVM 就是一个巨大的运行时,负责加载字节码、垃圾回收、即时编译等。你的 .class 代码是跑在 JVM 这个"虚拟操作系统"里的。
  • Go : Go 程序虽然编译成二进制,但它内部包含了一个轻量级的运行时 ,主要负责Goroutine 调度垃圾回收。即使你写一个空程序,编译出的二进制文件里也带着这个运行时。

2. Rust 的"无运行时"到底指什么?

Rust 说它"没有运行时",是指它没有上述那种重量级的、必须预先加载的、侵入式的运行时环境

具体来说,Rust 没有:

  • 垃圾回收器 (GC)
  • JIT 编译器
  • 复杂的线程调度模型(Rust 直接使用操作系统的原生线程 1:1 模型)
  • 反射机制

那么 Rust 程序怎么运行?

Rust 采用的是 "零开销抽象""一切尽在编译时" 的理念。

  1. 编译为原生机器码 :Rust 代码直接被 LLVM 编译器编译成当前 CPU 可以直接执行的机器码 。编译完成后,它就是一个普通的 .exe (Windows) 或 ELF (Linux) 文件。运行它和运行一个 C 程序没有任何区别------直接交给 CPU 执行

  2. 内存管理是代码的一部分 :Rust 独特的所有权系统和借用检查器,在编译时将内存管理的逻辑直接生成到最终的机器码里。drop 函数(类似析构函数)会在变量离开作用域时被静态插入 到代码中。内存的释放时机在编译期就确定了,而不是在运行时由 GC 线程说了算。

  3. "运行时"就是操作系统 :Rust 程序执行 println! 宏时,最终会调用操作系统的系统调用(比如 Linux 的 write)。可以说,Rust 把运行时的控制权完全交给了操作系统和 CPU

3. 一个简单的对比

假设有一个变量 x 离开了作用域:

  • Java: 对象变成"垃圾",等待 GC 线程在某个不确定的时间点扫描到并回收。这期间有额外内存开销。
  • Go : 编译器在函数末尾(或合适位置)插入 runtime.defer 调用,复杂的 GC 逻辑在运行时执行。
  • Rust : 编译器在 x 离开作用域的地方,直接生成了调用 free (或类似) 的汇编指令。没有函数调用开销,没有额外的线程扫描。

4. Rust 真的"零运行时"吗?

严格来说,Rust 还是有"运行时"的,只是这个概念非常

Rust 的 std 标准库在程序启动时需要做一些基本的初始化工作,比如:

  • 设置栈溢出保护
  • 处理命令行参数 std::env::args
  • 初始化 println! 等宏所需的输出流
  • 在 panic 时进行栈回溯

但这些工作代价极小,且是一次性的。对于 no_std 环境(如嵌入式系统、操作系统内核开发),你甚至可以连这层薄薄的运行时也去掉,Rust 程序可以直接从 #[no_mangle] pub extern "C" fn main() -> ! 开始执行,没有任何预置代码。

5.总结

  • 其他语言的"运行时":像一个虚拟的操作系统,程序运行在一个由虚拟机或运行时库提供的隔离环境中。
  • Rust 的"无运行时":程序就是普通的机器码,直接运行在物理 CPU 和操作系统之上。它没有垃圾回收、JIT 或复杂的协程调度器。

"没有运行时"的直接好处就是:

  • 启动极快:不需要启动 JVM 或初始化 GC。
  • 性能可预测:没有 GC 的"世界暂停"。
  • 内存占用低:没有运行时本身占用的内存。
  • 适合嵌入式:能运行在极其严苛的资源限制下。

一句话总结:Rust 把原本需要在程序运行时做的工作,尽可能地挪到了编译期完成。 编译后的产物就是一个"裸奔"的、性能极高的可执行文件。


参考文献

Rust Programming Language

相关推荐
love530love2 小时前
从零搭建本地版 Claurst:基于 Rust 重构的 Claude Code 终端编码助手 + LM Studio 模型接入测试
开发语言·人工智能·windows·重构·rust·lm studio·claude code
Tomhex1 天前
Rust数组与Vec的核心差异解析
rust
橘子编程1 天前
编程语言全指南:从C到Rust
java·c语言·开发语言·c++·python·rust·c#
亿牛云爬虫专家1 天前
学术文献爬虫 OOM 崩溃与 403 风暴
爬虫·rust·爬虫代理·403·oom killer·学术文献·403 forbidden
土豆12502 天前
Tauri 入门与实践:用 Rust 构建你的下一个桌面应用
前端·rust
土豆12502 天前
Rust 错误处理实战:anyhow + thiserror 的黄金搭档
rust
Zarek枫煜2 天前
C3 编程语言 - 现代 C 的进化之选
c语言·开发语言·青少年编程·rust·游戏引擎
咚为2 天前
Rust 经典面试题255道
开发语言·面试·rust
@atweiwei2 天前
用 Rust 构建 LLM 应用的高性能框架
开发语言·后端·ai·rust·langchain·llm