本文最后更新于 2026年10月30日。
我实测easytier只有一个gui进程,占用50M内存;tailscale三个进程,累计占用约110M内存。
Tailscale 和 EasyTier 在内存占用上存在明显差异,主要是由它们的开发语言、底层架构设计以及功能完整度决定的。
一、 两者的开发语言
-
Tailscale:主要使用 Go 语言(Golang) 编写(其核心客户端
tailscaled、控制面协议、协调服务器等均由 Go 实现)。 -
EasyTier:使用 Rust 语言(配合 Tokio 异步框架)编写。
二、 为什么 Tailscale 的内存占用比 EasyTier 高很多?
1. 语言运行时与内存管理机制(Go GC vs. Rust)
-
Go 语言的特点:Go 拥有自动垃圾回收机制(GC)和较重的运行时(Runtime)。为了追求吞吐量和运行效率,Go 的 GC 策略通常会占用并保留相对较多的虚拟内存和物理内存(以空间换时间)。此外,Go 的每个 Goroutine(协程)虽然很轻量,但运行时也会占用一定的基础内存开销。
-
Rust 语言的特点:Rust 采用所有权(Ownership)和生命周期系统,没有垃圾回收器(GC),也没有笨重的运行时。Rust 编译出的程序内存分配极为精准且开销极低,用多少释放多少,因此其常驻内存(RSS)通常可以做到非常小。
2. 用户态网络栈(gVisor Netstack)的开销
-
Tailscale 为了实现跨平台的高效虚拟网卡和网络路由,在其客户端内部嵌入了一套基于 Go 语言实现的完整用户态 TCP/IP 网络栈(借鉴了 Google 的 gVisor 项目中的
netstack)。 -
这套网络栈需要在用户态维护大量的网络连接状态、缓冲区和缓存队列,这在 Go 语言中会消耗相当可观的内存。而很多轻量级工具(或直接基于内核/轻量抽象的工具)则会精简这部分开销。
3. 功能生态与内置组件的差异
Tailscale 的客户端(tailscaled)不仅仅是一个简单的组网工具,它打包了非常庞大且丰富的企业级功能。这些功能即使在没有显式使用时,其代码逻辑和数据结构也在进程中待命:
-
MagicDNS:内置完整的 DNS 客户端与本地 DNS 服务器。
-
DERP 中继与 NAT 穿透:维护复杂的节点状态、多路复用连接及候选路径。
-
高级功能:如 Tailscale Serve / Funnel(反向代理)、SSH、Taildrop(文件传输)、Subnet Router(子网路由器)以及节点共享等。
-
相比之下,EasyTier 的定位更偏向于精简、去中心化的 P2P 虚拟局域网和 SD-WAN 核心,专注于底层的组网、路由和 WireGuard 加密,没有集成那么多面向企业和复杂应用层的庞大附加功能。
总结
-
EasyTier 赢在 Rust 的零成本抽象与轻量无 GC 特性,加之其功能更聚焦于核心组网,因此内存占用极低(通常只需几兆到十几兆)。
-
Tailscale 选择 Go 语言是为了开发效率、安全性和跨平台生态的丰富性,同时由于其内置了用户态 TCP/IP 栈(gVisor)以及极为全面的附加功能,导致其进程常驻内存通常在几十兆甚至上百兆不等。如果你的设备内存(如路由器、嵌入式设备)非常吃紧,或者追求极致的轻量化,Rust 编写的工具(如 EasyTier)在内存表现上确实更有优势。