0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Edge の「メモリ喰い過ぎ問題」を解決する

Last updated at Posted at 2025-03-22

動機

最近 Edge に移行しました。けど、やっぱり Chromium 系のブラウザはメモリ喰うなぁ、ということで Edge のメモリ使用量を削減してみます。

環境

Windows 10 22H2
rustc 1.85.1

結果

output.gif

msedge.exe が合計で 500MB ぐらい消費していますが、cargo runした直後にほぼ 0MB になりました!:tada:

解説

すみません、以前の記事を 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でラップしていきたいと思います。おわり。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?