# 帳票設計書 13-制約メモリ量

## 概要

本ドキュメントは、libuvライブラリが提供するcgroupsやジョブオブジェクト等によるメモリ制約量取得機能（uv_get_constrained_memory）の帳票設計書である。

### 本帳票の処理概要

uv_get_constrained_memory() APIは、cgroups（Linux）やrlimit等のメカニズムによって設定されたメモリ制約量をバイト単位で返却する関数である。

**業務上の目的・背景**：コンテナ環境（Docker、Kubernetes等）では、プロセスに対してメモリ制限が設定されることが一般的である。uv_get_total_memory()はホスト全体の物理メモリ量を返すが、コンテナ内で実際に利用可能なメモリ量はcgroupsの制約値により制限される。本APIはこの制約値を取得することで、アプリケーションがコンテナ環境で適切なメモリ管理を行えるようにする。

**帳票の利用シーン**：コンテナ環境でのメモリ制限の確認、Node.jsのヒープサイズ上限の動的決定、メモリ使用量がcgroup制限に近づいた際の警告、OOMKill回避のためのリソース管理。

**主要な出力内容**：
1. メモリ制約量（uint64_t型、バイト単位）。制約が存在しない場合は0を返却。

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

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

## 帳票種別

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

## 利用画面

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

## 出力形式

### 基本仕様

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

## 帳票レイアウト

### レイアウト概要

```
┌─────────────────────────────────────┐
│  メモリ制約量（バイト単位）           │
│  型: uint64_t                       │
│  範囲: 0 〜 UINT64_MAX             │
│  ※ 0は制約なしを意味する            │
└─────────────────────────────────────┘
```

### ヘッダー部

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

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | メモリ制約量 | cgroups/rlimit等による制約量 | cgroups ファイルシステム / rlimit | uint64_t（バイト） | 8バイト |

### フッター部

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

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| なし | 引数不要。システムのメモリ制約値を返却 | N/A |

### ソート順

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

### 改ページ条件

改ページは発生しない（単一スカラー値の返却）。

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

### 参照テーブル一覧

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

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

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

| プラットフォーム | データソース | 備考 |
|----------------|-------------|------|
| Linux (cgroupv1) | /sys/fs/cgroup/memory/.../memory.soft_limit_in_bytes, memory.limit_in_bytes | soft_limitとlimit_in_bytesの小さい方を使用 |
| Linux (cgroupv2) | /sys/fs/cgroup/.../memory.max, memory.high | maxとhighの小さい方を使用 |
| Linux (rlimit) | getrlimit(RLIMIT_AS) | cgroupとrlimitの小さい方を返却 |
| macOS/Darwin | getrlimit(RLIMIT_AS) | uv__get_rlimit_max_memory()を使用 |
| Windows | N/A | 常に0を返却（メモリ制約が不明） |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 制約メモリ量(Linux) | min(cgroup_limit, rlimit_limit) | なし | cgroupとrlimitの小さい方 |
| cgroup制約値 | min(high, max) | なし | UINT64_MAXは無制限を意味 |
| cgroupv1最大値判定 | LONG_MAX & ~(PAGE_SIZE - 1) | なし | cgroupv1固有の最大値パターン |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[uv_get_constrained_memory 呼び出し] --> B{プラットフォーム判定}
    B -->|Linux| C[/proc/self/cgroup 読取]
    B -->|macOS| D[uv__get_rlimit_max_memory 呼び出し]
    B -->|Windows| E[0を返却]
    C --> F{cgroupバージョン判定}
    F -->|v1| G[cgroupv1のmemory制約読取]
    F -->|v2| H[cgroupv2のmemory制約読取]
    G --> I[min high,max 算出]
    H --> I
    I --> J[rlimit制約取得]
    J --> K[min cgroup,rlimit を返却]
    D --> L[rlimit値を返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 制約なし | メモリ制約が設定されていない場合 | なし（戻り値0） | 0が返却される。uv_get_total_memory()を代替として使用 |
| 取得失敗 | cgroupファイルの読取失敗 | なし（戻り値0） | 0が返却される |

## パフォーマンス要件

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

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

cgroupファイルシステムへのアクセスが必要となる。通常のコンテナ環境ではこれらのファイルは読み取り可能であるが、セキュリティポリシーにより制限されている環境では0が返却される。

## 備考

- Windowsでは常に0を返却する。Windowsにはcgroupsに相当するメカニズムがないため。
- UINT64_MAXは「無制限」を意味し、実質的な制約なしとして扱われる。
- cgroupv1とcgroupv2の判定は/proc/self/cgroupの先頭が"0::/"で始まるかどうかで行う。

---

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

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

### 推奨読解順序

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

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | linux.c | `src/unix/linux.c` | 2202行目: Linux実装。/proc/self/cgroupを読取り、cgroup制約とrlimit制約の最小値を返却 |
| 2-2 | darwin.c | `src/unix/darwin.c` | 123行目: macOS実装。uv__get_rlimit_max_memory()に委譲 |
| 2-3 | util.c (win) | `src/win/util.c` | 303行目: Windows実装。常に0を返却 |

**主要処理フロー（Linux）**:
1. **2202行目**: uv_get_constrained_memory関数定義開始
2. **2208行目**: /proc/self/cgroupを読み込み
3. **2209行目**: uv__get_cgroup_constrained_memory()でcgroup制約値を取得
4. **2210行目**: uv__get_rlimit_max_memory()でrlimit制約値を取得
5. **2213-2217行目**: cgroup_limitとrlimit_limitの小さい方を返却

#### Step 3: cgroupバージョン別の制約読取を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | linux.c | `src/unix/linux.c` | 2186行目: uv__get_cgroup_constrained_memory関数。cgroupv1/v2の判定と制約値取得 |
| 3-2 | linux.c | `src/unix/linux.c` | 2129行目: uv__get_cgroup1_memory_limits関数。cgroupv1のmemory controller制約読取 |
| 3-3 | linux.c | `src/unix/linux.c` | 2169行目: uv__get_cgroup2_memory_limits関数。cgroupv2のmemory.max/memory.high読取 |

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

```
uv_get_constrained_memory()  [Linux]
    │
    ├─ uv__slurp("/proc/self/cgroup", ...)
    │
    ├─ uv__get_cgroup_constrained_memory(buf)
    │      │
    │      ├─ (cgroupv1) uv__get_cgroup1_memory_limits()
    │      │      ├─ uv__cgroup1_find_memory_controller()
    │      │      └─ uv__read_uint64() x2 (soft_limit, limit)
    │      │
    │      └─ (cgroupv2) uv__get_cgroup2_memory_limits()
    │             └─ uv__read_uint64() x2 (memory.max, memory.high)
    │
    └─ uv__get_rlimit_max_memory()

uv_get_constrained_memory()  [macOS]
    │
    └─ uv__get_rlimit_max_memory()

uv_get_constrained_memory()  [Windows]
    │
    └─ return 0
```

### データフロー図

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

/proc/self/cgroup ───▶ cgroupバージョン判定
                       ├─ v1: memory.limit_in_bytes ─┐
                       └─ v2: memory.max/high    ────┤
                                                     ├──▶ min(cgroup, rlimit) ───▶ uint64_t
getrlimit(RLIMIT_AS) ───▶ rlimit制約値 ─────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（1833行目） |
| linux.c | `src/unix/linux.c` | ソース | Linux固有実装（2202行目）、cgroup処理（2104-2200行目） |
| darwin.c | `src/unix/darwin.c` | ソース | macOS固有実装（123行目） |
| util.c | `src/win/util.c` | ソース | Windows固有実装（303行目） |
