メモリ使用量を取得する

Recipe ID: sys-004

システム全体のメモリ使用量(合計、使用済み、空きなど)を取得する方法を解説します。
Tauri の標準 JavaScript API (プラグイン) では動的なメモリ情報は提供されていないため、Rust 側の sysinfo クレートを使用してカスタムコマンドを作成するのが一般的です。

前提条件

Rust モジュール (src-tauri/Cargo.toml) に sysinfo クレートを追加します。

[dependencies]
tauri = { version = "2.0.0", features = [] }
serde = { version = "1.0", features = ["derive"] }
sysinfo = "0.37"

Rust 側の実装

src-tauri/src/lib.rs (または main.rs) に、メモリ情報を取得して返すコマンドを実装します。

use tauri::command;
use sysinfo::System;

#[derive(serde::Serialize)]
struct MemoryStats {
    total: u64,
    used: u64,
    free: u64,
    used_percentage: f64,
}

#[command]
fn get_memory_stats() -> MemoryStats {
    let mut sys = System::new_all();
    sys.refresh_memory();

    let total = sys.total_memory();
    let used = sys.used_memory();
    let free = sys.free_memory();
    
    // total が 0 の場合のゼロ除算回避
    let used_percentage = if total > 0 {
        (used as f64 / total as f64) * 100.0
    } else {
        0.0
    };

    MemoryStats {
        total,
        used,
        free,
        used_percentage,
    }
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        // コマンドを登録
        .invoke_handler(tauri::generate_handler![get_memory_stats])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

解説

1. sysinfo::System: クロスプラットフォームでシステム情報を取得するための構造体です。
2. refresh_memory(): メモリ情報のスナップショットを更新します。
3. コマンド化: #[tauri::command] マクロで Rust 関数をフロントエンドから呼び出せるようにします。
4. シリアライズ: MemoryStats 構造体に serde::Serialize を実装することで、自動的に JSON オブジェクトとして JavaScript に渡されます。

サンプルコード (Frontend)

Rust で作成した get_memory_stats コマンドを呼び出す例です。

1. 基本的な呼び出し

import { invoke } from '@tauri-apps/api/core';

interface MemoryStats {
  total: number;
  used: number;
  free: number;
  used_percentage: number;
}

const formatBytes = (bytes: number) => {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};

async function showMemory() {
  try {
    const stats = await invoke<MemoryStats>('get_memory_stats');
    console.log('Total:', formatBytes(stats.total));
    console.log('Used:', formatBytes(stats.used));
    console.log('Free:', formatBytes(stats.free));
    console.log(`Usage: ${stats.used_percentage.toFixed(1)}%`);
  } catch (e) {
    console.error('Failed to fetching memory stats', e);
  }
}

showMemory();