# 機能設計書 150-メモリ情報取得

## 概要

本ドキュメントは、libuvのOS情報機能におけるシステムメモリ情報取得機能 `uv_get_free_memory()` / `uv_get_total_memory()` / `uv_get_constrained_memory()` / `uv_get_available_memory()` の設計仕様を定義する。

### 本機能の処理概要

4つの関数群により、システムのメモリに関する各種情報をバイト単位で取得する。空きメモリ量、総メモリ量、制限付きメモリ量（cgroup/rlimit）、利用可能メモリ量をそれぞれ取得できる。

**業務上の目的・背景**：システムリソース監視、メモリ使用率の計算、アプリケーションのメモリバジェット決定、キャッシュサイズの動的調整等で、システムのメモリ情報が必要となる。特にコンテナ環境（Docker/Kubernetes）ではcgroup制限を考慮した実効的なメモリ量を取得する `uv_get_constrained_memory()` と `uv_get_available_memory()` が重要である。

**機能の利用シーン**：メモリ使用率モニタリング、GCのしきい値設定、バッファサイズの動的調整、コンテナ環境でのリソース認識、ヘルスチェック機能の実装などに使用される。

**主要な処理内容**：
1. `uv_get_free_memory()`: OSから空きメモリ量を取得する
2. `uv_get_total_memory()`: OSから物理メモリ総量を取得する
3. `uv_get_constrained_memory()`: cgroup/rlimit等による制限メモリ量を取得する
4. `uv_get_available_memory()`: 実際に利用可能なメモリ量を取得する（cgroup制限考慮）

**関連システム・外部連携**：macOSでは `host_statistics()`/`sysctl()`、Linuxでは `/proc/meminfo`/`/proc/self/cgroup`/`sysinfo()`、一部プラットフォームではrlimitを使用する。

**権限による制御**：一般ユーザー権限で実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 29 | その他ユーティリティ | 主機能 | uv_get_free_memory()/total/constrained/available_memory()のAPI定義 |

## 機能種別

情報取得処理（システムリソース情報のリードオンリー参照）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| （なし） | - | - | 4関数ともパラメータなし | - |

### 入力データソース

OSのメモリ情報API、/procファイルシステム（Linux）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| uv_get_free_memory() 戻り値 | uint64_t | 空きメモリ量（バイト）。取得失敗時は0 |
| uv_get_total_memory() 戻り値 | uint64_t | 物理メモリ総量（バイト）。取得失敗時は0 |
| uv_get_constrained_memory() 戻り値 | uint64_t | 制限メモリ量（バイト）。制限なし/取得失敗時は0 |
| uv_get_available_memory() 戻り値 | uint64_t | 利用可能メモリ量（バイト）。取得失敗時は0 |

### 出力先

呼び出し元への戻り値として返却される。

## 処理フロー

### 処理シーケンス

```
[uv_get_free_memory - macOS版]
1. host_statistics(HOST_VM_INFO)でVM統計を取得
   └─ 失敗時は0を返却
2. free_count * sysconf(_SC_PAGESIZE)で空きメモリをバイト計算
3. 結果を返却

[uv_get_total_memory - macOS版]
1. sysctl(CTL_HW, HW_MEMSIZE)で物理メモリ総量を取得
   └─ 失敗時は0を返却
2. 結果をuint64_tとして返却

[uv_get_constrained_memory - macOS版]
1. uv__get_rlimit_max_memory()でRLIMIT_RSSから制限値を取得
2. 結果を返却

[uv_get_available_memory - macOS版]
1. host_statistics(HOST_VM_INFO)でVM統計を取得
2. (free_count + inactive_count + purgeable_count) * PAGE_SIZE で計算
3. 結果を返却

[uv_get_free_memory - Linux版]
1. /proc/meminfoから"MemAvailable:"を読み取る
   └─ 読み取り成功→結果を返却
2. フォールバック: sysinfo()のfreeram * mem_unitを使用

[uv_get_constrained_memory - Linux版]
1. /proc/self/cgroupからcgroupパスを取得
2. cgroupv1/v2のmemory.limitを読み取る
3. RLIMIT_RSSも考慮し、最小値を返却

[uv_get_available_memory - Linux版]
1. cgroupの制限メモリを取得
2. 制限がない場合 → uv_get_free_memory()を返却
3. 制限がtotalメモリ超 → uv_get_free_memory()を返却
4. cgroupの現在メモリ使用量を取得
5. constrained - current を計算して返却
```

### フローチャート

```mermaid
flowchart TD
    A[uv_get_available_memory Linux版] --> B[cgroup制限メモリ取得]
    B --> C{制限あり?}
    C -->|No| D[uv_get_free_memory を返却]
    C -->|Yes| E[uv_get_total_memory 取得]
    E --> F{制限 > total?}
    F -->|Yes| D
    F -->|No| G[cgroup現在使用量取得]
    G --> H[constrained - current を計算]
    H --> I[結果を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-150-01 | エラー時ゼロ | 全関数は取得失敗時に0を返す（エラーコードは返さない） | API呼び出し失敗時 |
| BR-150-02 | cgroup考慮 | uv_get_constrained_memory()はcgroup v1/v2の制限を考慮 | Linux |
| BR-150-03 | rlimit考慮 | uv_get_constrained_memory()はRLIMIT_RSSも考慮 | macOS等 |
| BR-150-04 | 利用可能メモリ計算 | macOS: free+inactive+purgeableの合計。Linux: cgroupベースまたはMemAvailable | プラットフォーム依存 |
| BR-150-05 | sysinfo フォールバック | Linux版free_memoryはMemAvailable読み取り失敗時にsysinfo()にフォールバック | Linux |

### 計算ロジック

- macOS free_memory: `info.free_count * sysconf(_SC_PAGESIZE)`
- macOS available_memory: `(info.free_count + info.inactive_count + info.purgeable_count) * sysconf(_SC_PAGESIZE)`
- Linux available_memory (cgroup制限時): `constrained_memory - current_memory_usage`
- sysinfo-memory版: `info.freeram * info.mem_unit`、`info.totalram * info.mem_unit`

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし (0返却) | 取得失敗 | OS API呼び出し失敗 | 戻り値0をチェックしてフォールバック処理を行う |

### リトライ仕様

再試行可能。一時的なリソース不足の場合は再試行で成功する可能性がある。

## トランザクション仕様

該当なし。

## パフォーマンス要件

OS APIへの問い合わせを伴う。Linux版は/procファイルの読み取りを含む。各関数はミリ秒以下で完了する。

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

- メモリ情報はシステムリソースの可視性を提供するが、セキュリティリスクは低い
- コンテナ環境ではcgroup制限が適切に反映されることを確認すること

## 備考

- `uv_get_free_memory()` はLinuxでは `MemAvailable:` を使用し、これは単純な空きメモリではなくページキャッシュ等を考慮した実質的な利用可能メモリに近い値
- `uv_get_available_memory()` はcgroup制限下での実効的な利用可能メモリを返す
- sysinfo-memory.c は sysinfo() ベースの汎用実装を提供する（一部プラットフォームで使用）
- 4関数はすべてuint64_tを返し、エラーコードは返さない設計

---

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

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

### 推奨読解順序

#### Step 1: API宣言を確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | 4関数のAPI宣言（L1831-1834） |

**読解のコツ**: 4関数はすべてvoid引数でuint64_t戻り値。エラー時は0を返す設計のため、0と正常値0の区別がつかない点に注意。

#### Step 2: macOS版の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | darwin.c | `src/unix/darwin.c` | macOS版4関数の実装 |

**主要処理フロー**:
- **98-108行目**: `uv_get_free_memory()` - `host_statistics(HOST_VM_INFO)` でVM統計取得、`free_count * PAGE_SIZE` で計算
- **111-120行目**: `uv_get_total_memory()` - `sysctl(CTL_HW, HW_MEMSIZE)` で物理メモリ総量取得
- **123-125行目**: `uv_get_constrained_memory()` - `uv__get_rlimit_max_memory()` でRLIMIT_RSS取得
- **128-138行目**: `uv_get_available_memory()` - `host_statistics` で `free_count + inactive_count + purgeable_count` の合計にPAGE_SIZEを乗算

#### Step 3: Linux版の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | linux.c | `src/unix/linux.c` | Linux版実装 |

**主要処理フロー**:
- **2058-2071行目**: `uv_get_free_memory()` - `/proc/meminfo` の "MemAvailable:" 読み取り、失敗時は `sysinfo()` にフォールバック
- **2074-2084行目**: `uv_get_total_memory()` - `/proc/meminfo` の "MemTotal:" 読み取り、フォールバックあり
- **2202-2213行目**: `uv_get_constrained_memory()` - cgroup v1/v2 + RLIMIT_RSSの最小値
- **2259-2283行目**: `uv_get_available_memory()` - cgroup制限と現在使用量からの計算

#### Step 4: sysinfo汎用版を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | sysinfo-memory.c | `src/unix/sysinfo-memory.c` | sysinfo()ベースの汎用実装 |

**主要処理フロー**:
- **28-34行目**: `uv_get_free_memory()` - `sysinfo()` で `freeram * mem_unit` を計算
- **36-42行目**: `uv_get_total_memory()` - `sysinfo()` で `totalram * mem_unit` を計算

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

```
uv_get_free_memory()                          [公開API]
    ├─ [macOS] host_statistics(HOST_VM_INFO)  [OS API]
    ├─ [Linux] uv__read_proc_meminfo()        [内部関数]
    │    └─ /proc/meminfo 読み取り
    │    └─ [フォールバック] sysinfo()
    └─ [sysinfo版] sysinfo()                  [OS API]

uv_get_total_memory()                         [公開API]
    ├─ [macOS] sysctl(CTL_HW, HW_MEMSIZE)    [OS API]
    ├─ [Linux] uv__read_proc_meminfo()
    └─ [sysinfo版] sysinfo()

uv_get_constrained_memory()                   [公開API]
    ├─ [macOS] uv__get_rlimit_max_memory()    [内部関数]
    └─ [Linux] cgroup v1/v2 + rlimit

uv_get_available_memory()                     [公開API]
    ├─ [macOS] host_statistics(HOST_VM_INFO)
    ├─ [Linux] cgroup制限 - 現在使用量
    │    ├─ uv__get_cgroup_constrained_memory()
    │    ├─ uv_get_total_memory()
    │    ├─ uv_get_free_memory()
    │    └─ uv__get_cgroup1_current_memory() / uv__read_uint64()
    └─ [Other] uv_get_free_memory()にフォールバック
```

### データフロー図

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

OS メモリ情報 ──────────▶ uv_get_free_memory()          ──▶ uint64_t (バイト)
/proc/meminfo ──────────▶ uv_get_total_memory()         ──▶ uint64_t (バイト)
cgroup制限 ─────────────▶ uv_get_constrained_memory()   ──▶ uint64_t (バイト)
rlimit ─────────────────▶ uv_get_available_memory()     ──▶ uint64_t (バイト)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言 (L1831-1834) |
| darwin.c | `src/unix/darwin.c` | ソース | macOS版実装 (L98-138) |
| linux.c | `src/unix/linux.c` | ソース | Linux版実装 (L2058-2283) |
| sysinfo-memory.c | `src/unix/sysinfo-memory.c` | ソース | sysinfo()ベースの汎用実装 |
| freebsd.c | `src/unix/freebsd.c` | ソース | FreeBSD版実装 |
| openbsd.c | `src/unix/openbsd.c` | ソース | OpenBSD版実装 |
| netbsd.c | `src/unix/netbsd.c` | ソース | NetBSD版実装 |
| aix.c | `src/unix/aix.c` | ソース | AIX版実装 |
| sunos.c | `src/unix/sunos.c` | ソース | Solaris版実装 |
| util.c | `src/win/util.c` | ソース | Windows版実装 |
