動機
最近 Edge に移行しました。けど、やっぱり Chromium 系のブラウザはメモリ喰うなぁ、ということで Edge のメモリ使用量を削減してみます。
環境
Windows 10 22H2
rustc 1.85.1
結果
msedge.exe が合計で 500MB ぐらい消費していますが、cargo run
した直後にほぼ 0MB になりました!
解説
すみません、以前の記事を windows crate に置き換えただけです。
ソースコード
Cargo.toml
[package]
name = "be_on_edge"
version = "0.1.0"
edition = "2024"
[dependencies]
anyhow = "1.0"
[dependencies.windows]
version = "0.60"
features = [
"Win32_System_Diagnostics_ToolHelp",
"Win32_System_ProcessStatus",
"Win32_System_Threading",
]
main.rs
use std::ffi::CStr;
use std::thread;
use std::time::Duration;
use anyhow::Result;
use windows::{
Win32::{
Foundation::HANDLE,
System::{
Diagnostics::ToolHelp::{
CreateToolhelp32Snapshot, PROCESSENTRY32, Process32First, Process32Next,
TH32CS_SNAPPROCESS,
},
ProcessStatus::EmptyWorkingSet,
Threading::{OpenProcess, PROCESS_ALL_ACCESS},
},
},
core::Owned,
};
struct BeOnEdge {
entry: PROCESSENTRY32,
snap_shot: Owned<HANDLE>,
}
impl BeOnEdge {
fn new() -> Result<Self> {
let mut entry = PROCESSENTRY32 {
dwSize: size_of::<PROCESSENTRY32>() as _,
..Default::default()
};
let snap_shot = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) }?;
let snap_shot = unsafe { Owned::new(snap_shot) };
unsafe { Process32First(*snap_shot, &mut entry)? };
Ok(Self { entry, snap_shot })
}
}
impl Iterator for BeOnEdge {
type Item = ();
fn next(&mut self) -> Option<Self::Item> {
unsafe { Process32Next(*self.snap_shot, &mut self.entry).ok()? };
let exe = unsafe {
CStr::from_ptr(self.entry.szExeFile.as_ptr() as _)
.to_str()
.ok()?
};
if exe.eq("msedge.exe") {
let handle =
unsafe { OpenProcess(PROCESS_ALL_ACCESS, false, self.entry.th32ProcessID).ok()? };
let handle = unsafe { Owned::new(handle) };
unsafe { EmptyWorkingSet(*handle).ok()? };
}
Some(())
}
}
fn main() {
loop {
BeOnEdge::new().unwrap().for_each(|_| {});
thread::sleep(Duration::from_secs(5));
}
}
肝はwindows::core::Owned
という構造体です(handle.rs)。リンク先の実装を見れば分かるように、この構造体はFree
というトレイトを実装したなにかをメンバに持ち、Owned
がドロップするときにfree
関数を呼んでくれます。以前はHANDLE
をラップする構造体を自分で書いていましたが、もうその必要はないですね。Free
トレイトを実装しているのはHANDLE
だけじゃなくて、HFONT
とかHBITMAP
とかいろいろな構造体で実装されているので、これからは積極的にOwned
でラップしていきたいと思います。おわり。