# 通知設計書 41-メモリ使用量モニター

## 概要

本ドキュメントは、JenkinsのMemoryUsageMonitor（メモリ使用量モニター）に関する通知設計書である。JenkinsコントローラーのJVMメモリ使用状況を継続的に監視し、視覚的なグラフとして管理者に提示する機能について記述する。

### 本通知の処理概要

MemoryUsageMonitorは、JenkinsコントローラーのJVMメモリ使用状況をリアルタイムで監視・記録し、時系列グラフとして可視化する定期実行型のシステムモニターである。

**業務上の目的・背景**：Jenkinsは長時間稼働するCIサーバーであり、メモリリークや過剰なメモリ消費はシステムの安定性に直接影響を与える。管理者がメモリ使用状況のトレンドを把握することで、OutOfMemoryエラーの予兆を検知し、事前にヒープサイズの調整やジョブの見直しなどの対策を講じることが可能となる。

**通知の送信タイミング**：このモニターは10秒間隔で定期的にメモリ使用状況を収集する。データ収集はPeriodicWork拡張ポイントを利用しており、Jenkins起動後にランダムな初期遅延を経てから開始される。収集されたデータはMultiStageTimeSeriesに蓄積され、3つの時間スケール（Short: 10秒、Medium: 1分、Long: 1時間）でグラフ表示される。

**通知の受信者**：Jenkins管理者およびシステム管理権限（Jenkins.SYSTEM_READまたはJenkins.MANAGE権限）を持つユーザーが対象となる。専用のWebインターフェースを通じてグラフを閲覧できる。

**通知内容の概要**：ヒープメモリとノンヒープメモリの使用量（Used）と最大容量（Total）が時系列グラフとして表示される。グラフは赤色で使用中メモリ、青色で最大メモリ容量を示す。

**期待されるアクション**：管理者は定期的にメモリ使用グラフを確認し、異常なメモリ増加傾向やメモリ不足の予兆を検知した場合、JVMヒープサイズの調整、不要なプラグインの削除、ジョブの最適化などの対策を実施する。

## 通知種別

システム監視・アプリ内通知（Webダッシュボード表示）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 定期ポーリング（10秒間隔） |
| 優先度 | 中（情報提供目的） |
| リトライ | 無（メモリ取得失敗時はスキップ） |

### 送信先決定ロジック

メモリ使用状況データはJenkinsコントローラー内のMultiStageTimeSeriesオブジェクトに蓄積される。Webインターフェース（`/hudson.diagnosis.MemoryUsageMonitor/`）にアクセスしたユーザーに対して、権限チェック後にグラフが表示される。

## 通知テンプレート

### Webインターフェースの場合

| 項目 | 内容 |
|-----|------|
| 画面タイトル | JVM Memory Usage |
| 表示形式 | 時系列グラフ（PNG画像） |
| グラフサイズ | 500x300ピクセル |

### 本文テンプレート

```
JVM Memory Usage

Timespan: [Short] [Medium] [Long]

[メモリ使用量グラフ表示]
- 赤線: Used（使用中メモリ）
- 青線: Total（最大メモリ容量）
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| graph | PNG | 常時生成 | メモリ使用量の時系列グラフ画像 |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| type | 時間スケール（sec10/min/hour） | リクエストパラメータ | Yes（デフォルト: min） |
| heap.used | ヒープメモリ使用量（KB） | MemoryPoolMXBean.getCollectionUsage() | Yes |
| heap.max | ヒープメモリ最大容量（KB） | MemoryPoolMXBean.getCollectionUsage() | Yes |
| nonHeap.used | ノンヒープメモリ使用量（KB） | MemoryPoolMXBean.getCollectionUsage() | Yes |
| nonHeap.max | ノンヒープメモリ最大容量（KB） | MemoryPoolMXBean.getCollectionUsage() | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| スケジュール | 10秒間隔の定期実行 | 常時 | PeriodicWorkによる自動実行 |
| 画面操作 | ユーザーがメモリ監視画面にアクセス | 権限あり | グラフ表示リクエスト |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| メモリプール取得失敗 | MemoryPoolMXBean.getCollectionUsage()がnullを返した場合、該当プールはスキップ |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Jenkins起動] --> B[PeriodicWork初期化]
    B --> C[ランダム初期遅延後開始]
    C --> D[10秒間隔でdoRun実行]
    D --> E[MemoryPoolMXBean取得]
    E --> F{CollectionUsage取得可能?}
    F -->|可能| G[used/max値を累積]
    F -->|不可| H[該当プールスキップ]
    G --> I[KB単位に変換]
    H --> I
    I --> J[MultiStageTimeSeries更新]
    J --> K[10秒待機]
    K --> D

    L[ユーザーがグラフ画面アクセス] --> M{権限チェック}
    M -->|OK| N[TimeScale取得]
    N --> O[TrendChart生成]
    O --> P[グラフ画像レスポンス]
    M -->|NG| Q[アクセス拒否]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| N/A | データベースは使用しない | JVM内メモリに蓄積 |

### メモリ内データ構造

#### MultiStageTimeSeries

| 参照項目 | 用途 | 取得条件 |
|---------|------|---------|
| used (MultiStageTimeSeries) | メモリ使用量の時系列データ | heapまたはnonHeapグループから取得 |
| max (MultiStageTimeSeries) | メモリ最大容量の時系列データ | heapまたはnonHeapグループから取得 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| N/A | メモリ内更新 | MultiStageTimeSeriesへのデータ追加 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| CollectionUsage取得失敗 | GC後の使用量が取得できないメモリプール | 該当プールをスキップして処理続行 |
| 権限エラー | SYSTEM_READ/MANAGE権限なしでアクセス | アクセス拒否 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（次回定期実行で自動リカバリ） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| データ収集間隔 | 10秒 |
| グラフ生成 | リクエスト時にオンデマンド生成 |

### 配信時間帯

常時稼働（Jenkins稼働中は継続的にデータ収集）

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

- グラフ表示にはJenkins.SYSTEM_READまたはJenkins.MANAGE権限が必要（MemoryUsageMonitor.java 97行目）
- MemoryUsageMonitorActionはNoExternalUse制限により内部利用専用
- メモリ使用量情報はシステム監視目的であり、機密データは含まれない

## 備考

- MemoryUsageMonitorはPeriodicWorkを継承しており、Jenkins起動時に自動的にスケジュールされる
- グラフ表示は3つの時間スケール（Short: 10秒単位、Medium: 1分単位、Long: 1時間単位）をサポート
- メモリ使用量はガベージコレクション後の値（CollectionUsage）を使用するため、実際に生存しているオブジェクトの正確なフットプリントを反映
- version 2.505以降、MemoryUsageMonitorActionが追加され、`/hudson.diagnosis.MemoryUsageMonitor/heap`でヒープ情報にアクセス可能

---

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

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

### 推奨読解順序

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

メモリ使用量データを時系列で管理するMultiStageTimeSeriesの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MemoryUsageMonitor.java | `core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java` | MemoryGroupクラスの内部構造、usedとmaxフィールドの定義（62-66行目） |

**読解のコツ**: MemoryGroupはMemoryPoolMXBeanのリストを保持し、ヒープまたはノンヒープのメモリプールをグループ化する。MultiStageTimeSeriesは複数の時間スケールでデータを蓄積する。

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

定期実行の起点となるPeriodicWorkの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | PeriodicWork.java | `core/src/main/java/hudson/model/PeriodicWork.java` | 定期実行の仕組み、init()メソッド（104-112行目）でスケジュール登録 |
| 2-2 | MemoryUsageMonitor.java | `core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java` | getRecurrencePeriod()で10秒間隔を設定（112-114行目） |

**主要処理フロー**:
1. **104-112行目**: PeriodicWork.init()でExtensionListからすべてのPeriodicWorkを取得しスケジュール
2. **114-116行目**: schedulePeriodicWork()でTimer.get()にタスク登録

#### Step 3: 定期実行処理を理解する

10秒ごとに実行されるdoRun()メソッドの処理を追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MemoryUsageMonitor.java | `core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java` | doRun()メソッド（117-120行目）でheapとnonHeapを更新 |

**主要処理フロー**:
- **117-120行目**: doRun()でheap.update()とnonHeap.update()を呼び出し
- **75-91行目**: MemoryGroup.update()でMemoryPoolMXBeanからCollectionUsageを取得し、KB単位に変換してMultiStageTimeSeriesに追加

#### Step 4: グラフ生成処理を理解する

ユーザーリクエストに応じたグラフ生成の流れを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.jelly | `core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index.jelly` | グラフ表示画面のUI定義、timeパラメータによる時間スケール切り替え |
| 4-2 | MemoryUsageMonitor.java | `core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java` | doGraph()メソッド（96-99行目）でTrendChart生成 |

**主要処理フロー**:
- **96-99行目**: doGraph()で権限チェック後、TimeScale.parse()で時間スケールを解析し、MultiStageTimeSeries.createTrendChart()でグラフ生成

#### Step 5: Web API公開を理解する

version 2.505以降追加されたRootActionの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | MemoryUsageMonitorAction.java | `core/src/main/java/jenkins/diagnosis/MemoryUsageMonitorAction.java` | RootActionによるURL公開、getHeap()メソッド（49-52行目） |

**主要処理フロー**:
- **44-47行目**: getUrlName()でURLパス定義
- **49-52行目**: getHeap()で権限チェック後、ExtensionList経由でMemoryUsageMonitorのheapを返却

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

```
Jenkins起動
    │
    ├─ PeriodicWork.init()
    │      └─ schedulePeriodicWork(MemoryUsageMonitor)
    │             └─ Timer.get().scheduleAtFixedRate()
    │
    └─ [10秒ごと]
           └─ MemoryUsageMonitor.doRun()
                  ├─ heap.update()
                  │      └─ MemoryPoolMXBean.getCollectionUsage()
                  │             └─ MultiStageTimeSeries.update()
                  └─ nonHeap.update()
                         └─ MemoryPoolMXBean.getCollectionUsage()
                                └─ MultiStageTimeSeries.update()

ユーザーアクセス
    │
    └─ /hudson.diagnosis.MemoryUsageMonitor/
           └─ index.jelly
                  └─ MemoryGroup.doGraph()
                         └─ MultiStageTimeSeries.createTrendChart()
```

### データフロー図

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

MemoryPoolMXBean ───▶ MemoryUsageMonitor.doRun() ───▶ MultiStageTimeSeries
(JVM内部情報)               │                              (メモリ内蓄積)
                           │
                           ▼
                    MemoryGroup.update()
                           │
                           ▼
               [KB単位変換・データ蓄積]


HTTPリクエスト ───▶ MemoryGroup.doGraph() ───▶ TrendChart (PNG画像)
(type=sec10/min/hour)      │                      ▼
                           ▼               Webブラウザ表示
                    権限チェック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MemoryUsageMonitor.java | `core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java` | ソース | メイン監視クラス、定期実行とグラフ生成 |
| MemoryUsageMonitorAction.java | `core/src/main/java/jenkins/diagnosis/MemoryUsageMonitorAction.java` | ソース | RootAction実装、Web API公開 |
| PeriodicWork.java | `core/src/main/java/hudson/model/PeriodicWork.java` | ソース | 定期実行基底クラス |
| MultiStageTimeSeries.java | `core/src/main/java/hudson/model/MultiStageTimeSeries.java` | ソース | 時系列データ管理 |
| index.jelly | `core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index.jelly` | テンプレート | グラフ表示画面UI |
| Messages.properties | `core/src/main/resources/hudson/diagnosis/Messages.properties` | 設定 | メッセージリソース（USED, TOTAL） |
