Gur*_*ngh 5 rust rust-tokio rust-async-std
我有一个使用标准库的简单 TCP 回显服务器:
use std::net::TcpListener;
fn main() {
let listener = TcpListener::bind("localhost:4321").unwrap();
loop {
let (conn, _addr) = listener.accept().unwrap();
std::io::copy(&mut &conn, &mut &conn).unwrap();
}
}
Run Code Online (Sandbox Code Playgroud)
它使用大约 11 MB 的内存:
如果我将其转换为使用 tokio:
tokio = { version = "0.2.22", features = ["full"] }
Run Code Online (Sandbox Code Playgroud)
tokio = { version = "0.2.22", features = ["full"] }
Run Code Online (Sandbox Code Playgroud)
它使用 607 MB 的内存:
同样,使用 async_std:
async-std = "1.6.2"
Run Code Online (Sandbox Code Playgroud)
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
let mut listener = TcpListener::bind("localhost:4321").await.unwrap();
loop {
let (mut conn, _addr) = listener.accept().await.unwrap();
let (read, write) = &mut conn.split();
tokio::io::copy(read, write).await.unwrap();
}
}
Run Code Online (Sandbox Code Playgroud)
它还使用 607 MB 的内存:
为什么异步版本的程序使用的内存比同步版本多 55 倍?
我在这里尝试了一下,就像你在评论中所说的那样,有几个 64MB 的块:
\n==> pmap -d $(pidof tokio)\n3605: target/release/tokio\nAddress Kbytes Mode Offset Device Mapping\n\xe2\x80\xa6\n0000555b2a634000 132 rw--- 0000000000000000 000:00000 [ anon ]\n00007f2fec000000 132 rw--- 0000000000000000 000:00000 [ anon ]\n00007f2fec021000 65404 ----- 0000000000000000 000:00000 [ anon ]\n00007f2ff0000000 132 rw--- 0000000000000000 000:00000 [ anon ]\n00007f2ff0021000 65404 ----- 0000000000000000 000:00000 [ anon ]\n00007f2ff4000000 132 rw--- 0000000000000000 000:00000 [ anon ]\n00007f2ff4021000 65404 ----- 0000000000000000 000:00000 [ anon ]\n\xe2\x80\xa6\nRun Code Online (Sandbox Code Playgroud)\n这些块既不可读也不可写,因此它们不会被映射并且不使用任何内存。它们仅代表保留的地址空间。
\n此外,正如您所看到的,每个 65404K 块都紧跟在 132K 块之后。由于 65404+132 正好是 65536,我怀疑这些块代表了保留的地址空间,以防运行时需要稍后增加这些 132K 块之一。看看几个小时和几千个连接后的情况可能会很有趣。
\n