プロセスとスレッド
所要時間: 30分
前提知識: ps, top コマンド を使ったことがある
学べること:
- プロセスとは何か
- スレッドとは何か
- プロセスとスレッドの違い
- コンテキストスイッチのコスト
- Java の Platform Thread と Virtual Thread
この章で答える疑問
「ps で見える PID って何?」
「プロセスとスレッドの違いは?」
「なぜスレッドの方が軽い?」
「Java の Virtual Thread って何がすごいの?」
1. プロセスとは
1.1 プロセスの定義
プロセス = 実行中のプログラム
┌─────────────────────────────────────────────────────────────────────┐
│ │
│ プログラム(静的) → プロセス(動的) │
│ ───────────────── ────────────────── │
│ │
│ ディスク上のファイル → メモリに読み込まれて実行中 │
│ /usr/bin/java → PID: 12345 │
│ │
│ 設計図 → 動いている建物 │
│ │
└─────────────────────────────────────────────────────────────────────┘
1.2 プロセスが持つもの
各プロセスは以下の要素を持っています:
┌─────────────────────────────────────────────────────────────────────┐
│ プロセス (PID: 12345) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 仮想アドレス空間 │ │
│ │ ┌─────────────────────── ───────────────────────────────┐ │ │
│ │ │ コード領域(テキストセグメント) │ │ │
│ │ │ → 実行する命令(プログラム本体) │ │ │
│ │ ├──────────────────────────────────────────────────────┤ │ │
│ │ │ データ領域 │ │ │
│ │ │ → グローバル変数、静的変数 │ │ │
│ │ ├──────────────────────────────────────────────────────┤ │ │
│ │ │ ヒープ領域 │ │ │
│ │ │ → 動的に確保されるメモリ(malloc, new) │ │ │
│ │ ├──────────────────────────────────────────────────────┤ │ │
│ │ │ スタック領域 │ │ │
│ │ │ → 関数呼び出し、ローカル変数 │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ プロセス制御ブロック (PCB) │ │
│ │ ├── PID(プロセスID) │ │
│ │ ├── プロセス状態(実行中/待機中/停止中) │ │
│ │ ├── プログラムカウンタ(次の命令のアドレス) │ │
│ │ ├── CPU レジスタの内容 │ │
│ │ ├── メモリ管理情報 │ │
│ │ ├── 開いているファイル一覧(ファイルディスクリプタ) │ │
│ │ ├── 親プロセス ID (PPID) │ │
│ │ └── 優先度、使用時間などの統計情報 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
1.3 Linux での確認
# プロセス一覧
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 169784 13092 ? Ss Jan01 0:12 /sbin/init
java 5678 25.0 8.5 4568792 697624 ? Sl 10:30 5:23 java -jar app.jar
# 特定プロセスの詳細
$ cat /proc/5678/status
Name: java
State: S (sleeping)
Pid: 5678
PPid: 1234
Threads: 42
VmSize: 4568792 kB # 仮想メモリサイズ
VmRSS: 697624 kB # 物理メモリ使用量
1.4 プロセスの分離
重要: 各プロセスは独立したアドレス空間を持つ
┌───────────────────────────────────────────────────────────────────┐
│ 物理メモリ │
├───────────────────────────────────────────────────────────────────┤
│ │
│ プロセスA プロセスB プロセスC │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ │ │ │ │ │ │
│ │ 仮想 │ │ 仮想 │ │ 仮想 │ │
│ │ アドレス │ │ アドレス │ │ アドレス │ │
│ │ 空間 │ │ 空間 │ │ 空間 │ │
│ │ │ │ │ │ │ │
│ │ ×───────│────X────│───────× │ ← 相互にアクセス不可 │
│ │ │ │ │ │ │ │
│ └───────────┘ └───────────┘ └───────────┘ │
│ │
└───────────────────────────────────────────────────────────────────┘
プロセスAのメモリ破壊 → プロセスB, Cには影響しない
プロセスAがクラッシュ → プロセスB, Cは動き続ける