# 帳票設計書 15-常駐セットメモリサイズ

## 概要

本ドキュメントは、libuvライブラリが提供するプロセスの常駐セットサイズ（RSS）取得機能（uv_resident_set_memory）の帳票設計書である。

### 本帳票の処理概要

uv_resident_set_memory() APIは、現在のプロセスが物理メモリ上に保持しているページの合計サイズ（常駐セットサイズ: RSS）をバイト単位で取得する関数である。

**業務上の目的・背景**：プロセスのメモリ使用状況を監視することは、メモリリーク検出やパフォーマンス最適化において重要である。仮想メモリサイズとは異なり、RSSは実際に物理メモリ上に存在するページのサイズを示すため、メモリ圧迫の指標として信頼性が高い。Node.jsのprocess.memoryUsage()で返されるrss値はこのAPIを通じて取得される。

**帳票の利用シーン**：メモリリーク検出のための定期的なRSS監視、プロセスのメモリフットプリント計測、Node.js process.memoryUsage()の内部データソース、パフォーマンスプロファイリング。

**主要な出力内容**：
1. 常駐セットサイズ（size_t型、バイト単位、出力引数経由）

**帳票の出力タイミング**：アプリケーションコードからuv_resident_set_memory()を呼び出した時点で即座にポインタ経由で値を設定する。同期的に動作する。

**帳票の利用者**：Node.jsランタイム内部、アプリケーション開発者、メモリプロファイリングツール開発者

## 帳票種別

数値レポート（出力引数経由のスカラー値返却型）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | C API呼び出し | N/A | uv_resident_set_memory(&rss) 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | メモリ上の数値（size_t、ポインタ経由） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（出力引数） |
| 出力方法 | 出力引数（size_t* rss） |
| 文字コード | N/A |

## 帳票レイアウト

### レイアウト概要

```
┌─────────────────────────────────────┐
│  常駐セットサイズ（バイト単位）       │
│  型: size_t（出力引数経由）          │
│  戻り値: int（0=成功, 負数=エラー）  │
└─────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | N/A | ヘッダー部は存在しない | N/A | N/A |

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | RSS | プロセスの常駐セットサイズ | OS API（プラットフォーム依存） | size_t（バイト） | アーキテクチャ依存（4/8バイト） |

### フッター部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| N/A | N/A | フッター部は存在しない | N/A | N/A |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| rssポインタ | RSS値を格納するsize_t型ポインタ | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| N/A | N/A | N/A |

### 改ページ条件

改ページは発生しない。

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | データベースは参照しない | N/A |

### テーブル別参照項目詳細

#### プラットフォーム別データソース

| プラットフォーム | データソース | 備考 |
|----------------|-------------|------|
| Linux | /proc/self/stat（24番目のフィールド） | ページ単位の値にgetpagesize()を乗じる |
| macOS/Darwin | task_info(TASK_BASIC_INFO) | task_basic_info_data_t.resident_size |
| Windows | GetProcessMemoryInfo() | PROCESS_MEMORY_COUNTERS.WorkingSetSize |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| RSS(Linux) | /proc/self/statの24番目の値 * getpagesize() | なし | ページ数からバイト数に変換 |
| RSS(macOS) | info.resident_size | なし | task_infoから直接バイト値で取得 |
| RSS(Windows) | pmc.WorkingSetSize | なし | GetProcessMemoryInfoから直接バイト値で取得 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_resident_set_memory 呼び出し] --> B{プラットフォーム判定}
    B -->|Linux| C[/proc/self/stat 読取]
    B -->|macOS| D[task_info TASK_BASIC_INFO 呼び出し]
    B -->|Windows| E[GetProcessMemoryInfo 呼び出し]
    C --> F[最後の閉じ括弧を検索]
    F --> G[23番目のスペースまでスキップ]
    G --> H[strtolで値読取]
    H --> I[値 * getpagesize をrssに設定]
    I --> J[0 を返却]
    D --> K[info.resident_size をrssに設定]
    K --> J
    E --> L{GetProcessMemoryInfo成功?}
    L -->|Yes| M[pmc.WorkingSetSize をrssに設定]
    M --> J
    L -->|No| N[エラーコードを返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| ファイル読取失敗(Linux) | /proc/self/statの読取失敗 | なし | 負のエラーコードを返却 |
| パース失敗(Linux) | /proc/self/statの内容が想定外 | なし | UV_EINVALを返却 |
| API失敗(Windows) | GetProcessMemoryInfoの失敗 | なし | uv_translate_sys_errorでエラーコード変換 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1件（スカラー値） |
| 目標出力時間 | マイクロ秒オーダー |
| 同時出力数上限 | 制限なし |

## セキュリティ考慮事項

自プロセスの情報のみを取得するため、セキュリティ上の特別な配慮は不要である。

## 備考

- 他のメモリ情報APIと異なり、戻り値はエラーコード（int型）であり、実際のRSS値は出力引数経由で返される。
- macOS実装ではassert(err == KERN_SUCCESS)が使用されており、task_info(TASK_BASIC_INFO)の失敗はlibuvのバグとして扱われる。
- Linux実装では/proc/self/statの解析において、プロセス名に括弧や空白が含まれる場合に対応するため、最後の')'を基点としてフィールドを数える。

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | 1286行目: uv_resident_set_memory(size_t* rss)の宣言 |

**読解のコツ**: 出力引数パターン。戻り値intはエラーコード、実データはポインタ経由。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | linux.c | `src/unix/linux.c` | 1640行目: Linux実装。/proc/self/statを解析 |
| 2-2 | darwin.c | `src/unix/darwin.c` | 154行目: macOS実装。task_info()を使用 |
| 2-3 | util.c (win) | `src/win/util.c` | 486行目: Windows実装。GetProcessMemoryInfo()を使用 |

**主要処理フロー（Linux）**:
1. **1640行目**: uv_resident_set_memory関数定義開始
2. **1648行目**: uv__slurp("/proc/self/stat", ...)でファイル内容を読み込み
3. **1653行目**: strrchr(buf, ')')で最後の閉じ括弧を検索
4. **1657-1661行目**: 23番目のスペースまでスキップ（RSS値は24番目のフィールド）
5. **1664行目**: strtolで数値に変換
6. **1668行目**: val * getpagesize()でバイト単位に変換してrssに設定

**主要処理フロー（macOS）**:
1. **154行目**: uv_resident_set_memory関数定義開始
2. **160行目**: task_info(mach_task_self(), TASK_BASIC_INFO, ...)呼び出し
3. **169行目**: info.resident_sizeをrssに設定

### プログラム呼び出し階層図

```
uv_resident_set_memory(size_t* rss)  [Linux]
    │
    └─ uv__slurp("/proc/self/stat", ...)
           └─ strrchr → strchr (22回) → strtol → *rss = val * getpagesize()

uv_resident_set_memory(size_t* rss)  [macOS]
    │
    └─ task_info(mach_task_self(), TASK_BASIC_INFO, ...)
           └─ *rss = info.resident_size

uv_resident_set_memory(size_t* rss)  [Windows]
    │
    └─ GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))
           └─ *rss = pmc.WorkingSetSize
```

### データフロー図

```
[入力]                    [処理]                      [出力]

size_t* rss      ───▶  OS API呼び出し          ───▶  *rss = RSS値(bytes)
                       ├─ /proc/self/stat             int 戻り値(0 or エラー)
                       ├─ task_info()
                       └─ GetProcessMemoryInfo()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（1286行目） |
| linux.c | `src/unix/linux.c` | ソース | Linux固有実装（1640行目） |
| darwin.c | `src/unix/darwin.c` | ソース | macOS固有実装（154行目） |
| util.c | `src/win/util.c` | ソース | Windows固有実装（486行目） |
