# 画面設計書 12-Executor Heap Histogram（エグゼキュータヒープヒストグラム）

## 概要

本ドキュメントは、Apache Spark Application UIのExecutorsタブ配下にあるExecutor Heap Histogram画面の設計内容を記述する。本画面は特定エグゼキュータのヒープヒストグラム（クラス別インスタンス数・バイト数）をテーブル形式で表示する。

### 本画面の処理概要

**業務上の目的・背景**：Sparkアプリケーションのメモリ問題（OutOfMemoryError、GC頻発等）の調査において、ヒープ上のオブジェクト分布を把握することが重要である。本画面により、運用者や開発者は特定エグゼキュータのJVMヒープにおけるクラス別のインスタンス数とバイト数を確認でき、メモリリークや過剰なオブジェクト生成の原因特定に役立てることができる。JDKのjmap -histoコマンドに相当する情報をWeb UI上で取得可能とする。

**画面へのアクセス方法**：Executors一覧画面（No.10）のテーブル内にある「Heap Histogram」リンクをクリックすることでアクセスする。URLパラメータとしてexecutorIdが必要である。spark.ui.heapHistogramEnabled設定（デフォルト: false）が有効である必要がある。

**主要な操作・処理内容**：
1. ヒープヒストグラムテーブルでクラス別のインスタンス数・バイト数を確認する
2. テーブルのカラムヘッダをクリックしてソートを切り替える
3. 対象エグゼキュータのメモリ使用パターンを分析する

**画面遷移**：Executors一覧画面（No.10）から遷移してくる。本画面からの遷移先はない。

**権限による表示制御**：spark.ui.heapHistogramEnabled（デフォルト: false）が有効の場合のみ画面にアクセスできる。ACL設定（spark.acls.enable）が有効な場合、閲覧権限が必要。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | Spark Web UI | 主機能 | 特定Executorのヒープヒストグラム（クラス別インスタンス数・バイト数）を表示する主処理 |
| 5 | Executorプロセス管理 | 主機能 | SparkContext.getExecutorHeapHistogramを呼び出しExecutorのヒープ情報を取得 |

## 画面種別

詳細

## URL/ルーティング

- パス: `/executors/heapHistogram/`
- パラメータ: `executorId` (必須) - 対象エグゼキュータのID
- 例: `/executors/heapHistogram/?executorId=1`

## 入出力項目

| 項目名 | 入出力 | 型 | 必須 | 説明 |
|--------|--------|------|------|------|
| executorId | 入力（URLパラメータ） | String | 必須 | 対象エグゼキュータのID |

## 表示項目

### Heap Histogram テーブル

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| Rank | Int | クラスのランキング（バイト数降順） |
| Instances | Long | 該当クラスのインスタンス数 |
| Bytes | Long | 該当クラスが使用しているバイト数 |
| Class Name | String | クラス名（JVM内部表現） |
| Module | String | モジュール名（Java 9+のモジュールシステム） |

## イベント仕様

### 1-カラムヘッダクリック（ソート）

テーブルヘッダのカラムをクリックすると、該当カラムでテーブルをソートする。sortableクラスにより標準のJavaScriptソート機能が適用される。

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | - | SELECT（リモート呼び出し） | SparkContext経由でExecutorにRPCリクエストを送信しヒープヒストグラムを取得 |

本画面はデータベースへの更新操作を行わない。エグゼキュータへのリモート呼び出しによりリアルタイムのヒープヒストグラムを取得する。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|--------------|----------|
| MSG-001 | エラー | "Error fetching heap histogram" | ヒープヒストグラム取得に失敗した場合 |
| MSG-002 | エラー | "Missing executorId parameter" | executorIdパラメータが未指定の場合 |

## 例外処理

- executorIdパラメータが未指定の場合: IllegalArgumentExceptionがスローされ、エラーページが表示される
- ヒープヒストグラム取得失敗時: "Error fetching heap histogram"メッセージが画面に表示される（対象Executorが停止済み・通信不可等）

## 備考

- spark.ui.heapHistogramEnabled（デフォルト: false）が無効の場合、ExecutorsTabに本ページは登録されない
- ヒープヒストグラムのデータはjmap -histo形式のテキストをパースして表示する
- 正規表現パターン `\s*([0-9]+):\s+([0-9]+)\s+([0-9]+)\s+(\S+)(.*)` でヒストグラムの各行を解析する
- ヘッダ行（num #instances #bytes ...）、セパレータ行、Total行はスキップされる
- ページ上部に取得時刻が「Updated at {日時}」形式で表示される

---

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

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

### 推奨読解順序

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

ヒープヒストグラムのデータ形式を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ExecutorHeapHistogramPage.scala | `core/src/main/scala/org/apache/spark/ui/exec/ExecutorHeapHistogramPage.scala` | 行32: 正規表現パターンの定義。jmap -histo出力フォーマット（rank, instances, bytes, className, module）を解析 |

**読解のコツ**: ヒープヒストグラムはjmap -histoコマンドのテキスト出力をそのまま文字列配列として受け取り、正規表現でパースする方式である。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ExecutorsTab.scala | `core/src/main/scala/org/apache/spark/ui/exec/ExecutorsTab.scala` | 行35-36: heapHistogramEnabledの判定。UI_HEAP_HISTOGRAM_ENABLED設定で制御 |
| 2-2 | ExecutorHeapHistogramPage.scala | `core/src/main/scala/org/apache/spark/ui/exec/ExecutorHeapHistogramPage.scala` | 行27-29: クラス定義。WebUIPage("heapHistogram")でURLパスを設定 |

**主要処理フロー**:
1. **行34-39**: renderメソッドでexecutorIdパラメータを取得・URLデコード
2. **行41**: sc.get.getExecutorHeapHistogram(executorId)でヒープヒストグラムを取得
3. **行43-70**: 正規表現で各行をパースし、テーブル行に変換
4. **行71-85**: テーブルHTMLを生成
5. **行87**: UIUtils.headerSparkPageでページ全体をラップ

#### Step 3: ページ登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ExecutorsTab.scala | `core/src/main/scala/org/apache/spark/ui/exec/ExecutorsTab.scala` | 行41-43: heapHistogramEnabledがtrueの場合のみattachPage |

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

```
ExecutorsTab.init() [行31-44]
    |
    +-- ExecutorHeapHistogramPage (UI_HEAP_HISTOGRAM_ENABLED=true時のみ登録)
            |
            +-- render(request) [行34]
                    |
                    +-- UIUtils.decodeURLParameter(executorId) [行35-36]
                    |
                    +-- sc.get.getExecutorHeapHistogram(executorId) [行41]
                    |       |
                    |       +-- SparkContext -> Executor RPC呼び出し
                    |
                    +-- 正規表現パターンマッチ [行44-70]
                    |       |
                    |       +-- pattern(rank, instances, bytes, name, module)
                    |       +-- pattern(rank, instances, bytes, name)
                    |
                    +-- テーブルHTML生成 [行71-85]
                    |
                    +-- UIUtils.headerSparkPage() [行87]
```

### データフロー図

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

executorId ──────────────> ExecutorHeapHistogramPage.render()
(URLパラメータ)                    |
                                   +---> SparkContext
                                   |     .getExecutorHeapHistogram() ──> RPC to Executor
                                   |           |                            (jmap -histo)
                                   |     Array[String] <──────────────
                                   |           |
                                   +---> 正規表現パース ─────────────> テーブルHTML
                                   |     (rank, instances, bytes,
                                   |      className, module)
                                   |
                                   +---> headerSparkPage() ────────> 完成ページHTML
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ExecutorHeapHistogramPage.scala | `core/src/main/scala/org/apache/spark/ui/exec/ExecutorHeapHistogramPage.scala` | ソース | メイン画面ページクラス |
| ExecutorsTab.scala | `core/src/main/scala/org/apache/spark/ui/exec/ExecutorsTab.scala` | ソース | タブ定義・ページ登録 |
| UIUtils.scala | `core/src/main/scala/org/apache/spark/ui/UIUtils.scala` | ソース | UI共通ユーティリティ |
| SparkContext.scala | `core/src/main/scala/org/apache/spark/SparkContext.scala` | ソース | getExecutorHeapHistogramメソッド |
