# 帳票設計書 14-利用可能メモリ量

## 概要

本ドキュメントは、libuvライブラリが提供する現在利用可能なメモリ量取得機能（uv_get_available_memory）の帳票設計書である。

### 本帳票の処理概要

uv_get_available_memory() APIは、cgroups等のメモリ制約を考慮した上で、現在アプリケーションが利用可能なメモリ量をバイト単位で返却する関数である。

**業務上の目的・背景**：コンテナ環境では、OSレベルの空きメモリ量とコンテナに割り当てられたメモリ量は異なる。uv_get_free_memory()がOS全体の空きメモリ量を返すのに対し、本APIはcgroupの制約値から現在の使用量を差し引いた「真に利用可能な量」を返す。これにより、コンテナ環境でのOOMKill回避やメモリ管理の精度が向上する。

**帳票の利用シーン**：コンテナ環境でのメモリ残量確認、バッファやキャッシュのサイズ動的調整、メモリ不足の予兆検知、ガベージコレクションのトリガー判定。

**主要な出力内容**：
1. 利用可能メモリ量（uint64_t型、バイト単位）

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

**帳票の利用者**：コンテナ化アプリケーション開発者、Node.jsランタイム内部、クラウドネイティブアプリケーション開発者

## 帳票種別

数値レポート（スカラー値返却型）

## 利用画面

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

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | メモリ上の数値（uint64_t） |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | N/A（関数戻り値） |
| 出力方法 | 関数戻り値 |
| 文字コード | N/A |

## 帳票レイアウト

### レイアウト概要

```
┌─────────────────────────────────────┐
│  利用可能メモリ量（バイト単位）       │
│  型: uint64_t                       │
│  範囲: 0 〜 UINT64_MAX             │
└─────────────────────────────────────┘
```

### ヘッダー部

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

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | 利用可能メモリ量 | cgroup制約を考慮した利用可能メモリ | cgroups + OS API | uint64_t（バイト） | 8バイト |

### フッター部

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

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| なし | 引数不要。cgroup制約考慮済みの利用可能メモリ量を返却 | N/A |

### ソート順

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

### 改ページ条件

改ページは発生しない。

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

### 参照テーブル一覧

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

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

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

| プラットフォーム | データソース | 備考 |
|----------------|-------------|------|
| Linux (cgroupv1) | memory.usage_in_bytes, cgroup制約値 | constrained - current |
| Linux (cgroupv2) | memory.current, cgroup制約値 | constrained - current |
| Linux (cgroup無効) | uv_get_free_memory() | cgroup制約がない場合はfree memoryにフォールバック |
| macOS/Darwin | host_statistics(HOST_VM_INFO) | free_count + inactive_count + purgeable_count |
| Windows | uv_get_free_memory() | GlobalMemoryStatusExのullAvailPhysに委譲 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 利用可能メモリ(Linux/cgroup有) | constrained - current | なし | constrained < currentの場合は0 |
| 利用可能メモリ(macOS) | (free_count + inactive_count + purgeable_count) * PAGE_SIZE | なし | 再利用可能なページも含む |
| 利用可能メモリ(Windows) | uv_get_free_memory()と同値 | なし | 委譲 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_get_available_memory 呼び出し] --> B{プラットフォーム判定}
    B -->|Linux| C[/proc/self/cgroup 読取]
    B -->|macOS| D[host_statistics 呼び出し]
    B -->|Windows| E[uv_get_free_memory に委譲]
    C --> F[cgroup制約値取得]
    F --> G{制約値 == 0?}
    G -->|Yes| H[uv_get_free_memory に委譲]
    G -->|No| I{制約値 > 総メモリ?}
    I -->|Yes| H
    I -->|No| J[cgroup現在使用量取得]
    J --> K{制約値 < 使用量?}
    K -->|Yes| L[0 を返却]
    K -->|No| M[制約値 - 使用量 を返却]
    D --> N[free+inactive+purgeable * PAGE_SIZE を返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| cgroup読取失敗 | /proc/self/cgroupの読取失敗 | なし（戻り値0） | Linuxで0が返却される |
| メモリ超過 | 使用量が制約値を超えている場合 | なし（戻り値0） | 一時的なバースト使用を示す |

## パフォーマンス要件

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

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

cgroupファイルシステムへのアクセスが必要。通常のコンテナ環境ではこれらのファイルは読み取り可能である。

## 備考

- macOS実装では、free_countに加えinactive_countとpurgeable_countも含めるため、uv_get_free_memory()より大きい値を返す場合がある。
- Linux実装では、cgroup制約がない場合やcgroup制約が総メモリ量を超えている場合はuv_get_free_memory()にフォールバックする。
- メモリ使用量が一時的に制約値を超える場合（バースト）は0を返却する。

---

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

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

### 推奨読解順序

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | linux.c | `src/unix/linux.c` | 2259行目: Linux実装。cgroup制約を考慮した利用可能メモリ算出 |
| 2-2 | darwin.c | `src/unix/darwin.c` | 128行目: macOS実装。host_statisticsからfree+inactive+purgeable算出 |
| 2-3 | util.c (win) | `src/win/util.c` | 308行目: Windows実装。uv_get_free_memory()に委譲 |

**主要処理フロー（Linux）**:
1. **2259行目**: uv_get_available_memory関数定義開始
2. **2265行目**: /proc/self/cgroupを読み込み
3. **2268行目**: cgroup制約値を取得
4. **2269-2270行目**: 制約値が0ならuv_get_free_memory()にフォールバック
5. **2272-2274行目**: 制約値が総メモリ量より大きい場合もフォールバック
6. **2277-2280行目**: cgroupバージョンに応じて現在使用量を取得
7. **2283-2284行目**: 制約値 < 使用量なら0を返却
8. **2286行目**: 制約値 - 使用量を返却

#### Step 3: cgroup現在使用量の取得を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | linux.c | `src/unix/linux.c` | 2221行目: cgroupv1のmemory.usage_in_bytes読取 |
| 3-2 | linux.c | `src/unix/linux.c` | 2245行目: cgroupv2のmemory.current読取 |

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

```
uv_get_available_memory()  [Linux]
    │
    ├─ uv__slurp("/proc/self/cgroup", ...)
    │
    ├─ uv__get_cgroup_constrained_memory(buf)
    │
    ├─ (制約なし) uv_get_free_memory()
    │
    ├─ uv_get_total_memory()  [制約値と比較用]
    │
    ├─ (cgroupv1) uv__get_cgroup1_current_memory(buf)
    │      └─ uv__read_uint64("memory.usage_in_bytes")
    │
    └─ (cgroupv2) uv__get_cgroup2_current_memory(buf)
           └─ uv__read_uint64("memory.current")

uv_get_available_memory()  [macOS]
    │
    └─ host_statistics(mach_host_self(), HOST_VM_INFO, ...)

uv_get_available_memory()  [Windows]
    │
    └─ uv_get_free_memory()
```

### データフロー図

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

/proc/self/cgroup    ───▶  cgroup制約値取得
cgroup memory files  ───▶  現在使用量取得        ───▶  constrained - current ───▶ uint64_t
/proc/meminfo        ───▶  フォールバック用
```

### 関連ファイル一覧

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