メモリリークしていないか検査する

Recipe ID: perf-006

長時間起動しているとアプリが重くなる、メモリ使用量が増え続けるといった症状がある場合、メモリリークを疑います。
Tauri ではフロントエンド(WebView)とバックエンド(Rust)の両方を調査する必要があります。

1. フロントエンドの調査 (Chrome DevTools)

開発ビルド (npm run tauri dev) で起動し、開発者ツールの Memory タブを使用します。

1. Heap Snapshot: 現在のメモリ状態を記録します。
2. 操作を行う(ページ遷移など)。
3. 再度 Heap Snapshot を取得。
4. Snapshot 間で比較 (Comparison) し、GC(ガベージコレクション)後も削除されずに残っているオブジェクト(Detached DOM nodes など)を探します。

特に addEventListener の解除忘れや、グローバル変数への参照残りが一般的な原因です。

2. Rust 側の調査 (Valgrind / Heaptrack)

Linux / macOS 環境であれば、プロファイリングツールを使用できます。

# heaptrack のインストール (Linux)
sudo apt install heaptrack

# ビルドしたバイナリを計測
heaptrack ./src-tauri/target/release/my-app

Windows の場は Visual Studio のパフォーマンスプロファイラを使用するか、Rust コード内で定期的にメモリ使用量をログ出力して監視します。

3. 定期的なメモリ監視の実装

sysinfo クレートを使用して、自身のメモリ使用量を定期的に記録する機能を埋め込んでおくと、ユーザー環境でのトラブルシューティングに役立ちます。

src-tauri ディレクトリで以下のコマンドを実行します。

cargo add sysinfo
// lib.rs
use sysinfo::{Pid, ProcessesToUpdate, System};
use std::{thread, time::Duration};

fn start_memory_monitor() {
    let pid = Pid::from_u32(std::process::id());
    
    thread::spawn(move || {
        let mut sys = System::new();
        loop {
            sys.refresh_processes(ProcessesToUpdate::Some(&[pid]), true);
            if let Some(process) = sys.process(pid) {
                println!("Memory: {} KB", process.memory());
            }
            thread::sleep(Duration::from_secs(60));
        }
    });
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    // メモリ監視を開始
    start_memory_monitor();

    tauri::Builder::default()
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}