# 画面設計書 63-ヒープダンプ

## 概要

本ドキュメントは、Jenkins CI/CDサーバーの「ヒープダンプ」画面の設計書です。

### 本画面の処理概要

JVMのヒープダンプをHPROF形式でダウンロードするための画面です。メモリリークの調査やパフォーマンス問題の診断に使用します。

**業務上の目的・背景**：Jenkinsサーバーでメモリリークやパフォーマンス問題が発生した場合、ヒープダンプを取得して分析することで原因を特定できます。この画面は、管理者がコマンドラインにアクセスすることなく、WebブラウザからJVMのヒープダンプを取得できるようにすることを目的としています。取得したヒープダンプファイルは、Eclipse MAT（Memory Analyzer Tool）やVisualVMなどのツールで分析できます。

**画面へのアクセス方法**：ノード詳細画面 > スクリプトコンソール > ヒープダンプ、またはマスターノードの場合は Jenkins管理画面 > システム情報からアクセスします。URLパス例: `/computer/{ノード名}/heapDump/` または `/manage/heapDump/`

**主要な操作・処理内容**：
1. 画面表示でヒープダンプの説明を確認
2. 「Download」ボタンをクリックしてヒープダンプを取得
3. HPROF形式のファイルがダウンロードされる
4. 外部ツールでヒープダンプを分析

**画面遷移**：ノード詳細画面から遷移、ダウンロード後は同画面に留まります

**権限による表示制御**：ADMINISTER権限を持つ管理者のみがアクセス・操作可能です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Jenkins本体 | 主機能 | JVMヒープダンプの取得 |
| 12 | コンピューター管理 | 補助機能 | 対象ノードの指定 |

## 画面種別

操作 / 診断

## URL/ルーティング

- URL: `/computer/{nodeName}/heapDump/` または `/manage/heapDump/`
- ルーティング: `RemotingDiagnostics.HeapDump` クラスが Staplerにより URLにバインドされます

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|-----|------|------|
| - | - | - | - | この画面には入力項目はありません |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| タイトル | 見出し | "Heap dump for {ノード名}" |
| 説明文 | テキスト | ヒープダンプの用途と注意事項 |
| Downloadボタン | ボタン | ヒープダンプをダウンロードするボタン |

## イベント仕様

### 1-Downloadボタン押下

ユーザーがDownloadボタンを押下した際の処理です。

**処理フロー**：
1. POSTリクエストで `heapdump.hprof` アクションを呼び出し
2. ADMINISTER権限のチェック
3. 対象ノード（マスターまたはエージェント）でヒープダンプを取得
4. 一時ファイルとしてHPROF形式で保存
5. ファイルをHTTPレスポンスとしてストリーミング
6. 一時ファイルを削除

**技術詳細**：
- ヒープダンプは `com.sun.management:type=HotSpotDiagnostic` MBeanの `dumpHeap` メソッドで取得
- ファイル形式: HPROF形式（バイナリ）
- Content-Type: `application/octet-stream`

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ヒープダンプ取得 | なし | ファイル作成/削除 | 一時ファイルを作成し、ダウンロード後に削除 |

### 一時ファイル仕様

| 項目 | 内容 |
|------|------|
| ファイル名パターン | `hudson-heapdump*.hprof` |
| 保存先 | システムの一時ディレクトリ |
| ライフサイクル | ダウンロード完了後に自動削除 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|---------|
| title | 見出し | Heap dump for {0} | 常時表示（{0}はノード名） |
| blurb | 説明 | ヒープダンプの説明文 | 常時表示 |
| Download | ボタン | Download | 常時表示 |

## 例外処理

| 例外条件 | 対応 | 表示内容 |
|---------|------|---------|
| 権限不足 | 403エラー | アクセス拒否画面へリダイレクト |
| JMException | 500エラー | ヒープダンプ取得失敗のエラーメッセージ |
| IOException | 500エラー | ファイル操作エラーのメッセージ |
| ノードオフライン | 500エラー | ノードに接続できない旨のエラー |

## 備考

- ヒープダンプの取得はJVMに負荷がかかるため、本番環境での使用には注意が必要です
- ヒープダンプファイルはメモリサイズに応じて数GBになる場合があります
- エージェントノードの場合、ヒープダンプはエージェントJVMから取得されます
- HotSpot JVMでのみ動作します（他のJVM実装では利用できない場合があります）

---

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

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

### 推奨読解順序

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

まず、ヒープダンプ機能の全体構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | RemotingDiagnostics.java | `core/src/main/java/hudson/util/RemotingDiagnostics.java` | HeapDumpインナークラスの構造、VirtualChannelの役割を理解 |

**読解のコツ**: `RemotingDiagnostics` は複数の診断機能を提供するユーティリティクラスです。`HeapDump` インナークラスが画面表示とダウンロード処理を担当します。

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

画面表示の起点となるファイルを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.jelly | `core/src/main/resources/hudson/util/RemotingDiagnostics/HeapDump/index.jelly` | 画面構造、権限チェック、フォームアクションを理解 |

**主要処理フロー**:
1. **行3**: `permission="${app.ADMINISTER}"` でADMINISTER権限チェック
2. **行4**: サイドパネルの表示（コンテキストに基づく）
3. **行6**: タイトル表示（ノード名を含む）
4. **行7-8**: 説明文の表示
5. **行10-12**: Downloadボタン（POSTフォーム）

#### Step 3: バックエンド処理を理解する

ヒープダンプ取得の実装を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RemotingDiagnostics.java (HeapDump) | `core/src/main/java/hudson/util/RemotingDiagnostics.java` | doHeapDump()メソッド（行216-228）を理解 |

**主要処理フロー**:
- **行207-214**: `HeapDump` クラスのコンストラクタ（owner, channel）
- **行216-217**: `@WebMethod(name = "heapdump.hprof")` と `@RequirePOST` でURLマッピング
- **行218-228**: `doHeapDump()` でヒープダンプ取得とレスポンス返却
- **行238-240**: `obtain()` で実際のヒープダンプ取得を委譲

#### Step 4: ヒープダンプ取得の実装を理解する

JMXを使用したヒープダンプ取得処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | RemotingDiagnostics.java (GetHeapDump) | `core/src/main/java/hudson/util/RemotingDiagnostics.java` | GetHeapDumpクラス（行180-201）を理解 |

**主要処理フロー**:
- **行184**: `MasterToSlaveCallable` を継承（リモート実行可能）
- **行187**: 一時ファイル作成 `hudson-heapdump*.hprof`
- **行188**: 既存ファイルを削除（JMXの要件）
- **行190-192**: MBeanServerから `dumpHeap` を呼び出し
- **行194**: `FilePath` としてファイルパスを返却

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

```
index.jelly (画面表示)
    │
    ├─ permission="${app.ADMINISTER}" ─── 権限チェック
    │
    └─ <form action="heapdump.hprof">
           │
           └─ HeapDump.doHeapDump() [@WebMethod(name="heapdump.hprof")]
                  │
                  ├─ owner.checkPermission(ADMINISTER) ─── 権限再チェック
                  │
                  ├─ rsp.setContentType("application/octet-stream")
                  │
                  ├─ obtain()
                  │      │
                  │      └─ RemotingDiagnostics.getHeapDump(channel)
                  │             │
                  │             └─ channel.call(new GetHeapDump())
                  │                    │
                  │                    ├─ File.createTempFile("hudson-heapdump", ".hprof")
                  │                    │
                  │                    ├─ MBeanServer.invoke(HotSpotDiagnostic, "dumpHeap")
                  │                    │
                  │                    └─ return new FilePath(hprof)
                  │
                  ├─ dump.copyTo(rsp.getOutputStream())
                  │
                  └─ dump.delete() ─── 一時ファイル削除
```

### データフロー図

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

Downloadボタン ─────▶ doHeapDump() ──────────────▶ heapdump.hprof
(POST)                    │                          (バイナリ)
                          ▼
                   channel.call(GetHeapDump)
                          │
                          ▼
                   MBeanServer.invoke() ──────────▶ 一時ファイル
                          │                              │
                          ▼                              ▼
                   FilePath(hprof) ─────────────▶ HTTPレスポンス
                          │                              │
                          ▼                              ▼
                   dump.delete() ───────────────▶ ファイル削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RemotingDiagnostics.java | `core/src/main/java/hudson/util/RemotingDiagnostics.java` | ソース | ヒープダンプ取得の主クラス |
| index.jelly | `core/src/main/resources/hudson/util/RemotingDiagnostics/HeapDump/index.jelly` | テンプレート | 画面表示用Jellyテンプレート |
| FilePath.java | `core/src/main/java/hudson/FilePath.java` | ソース | ファイル操作ユーティリティ |
| VirtualChannel.java | `remoting/src/main/java/hudson/remoting/VirtualChannel.java` | ソース | リモート通信チャネル |
