タブは どこから来て
どこへ消えるのか。

気づくと 30 個ぐらい開いてる。
そもそも「タブ」って、何?
CHROME の中身を覗く回

気づくと、タブ 30 個

動作が重くなる。「Chrome がメモリ食いすぎ」と怒られる。
でも、そもそも 「タブを開く」って何が起きてるのか、考えたことなかったなと。 — 一番身近なアプリの中身を、ちゃんと覗いたことがなかったので調べてみました。
今日は 「タブが生まれてから消えるまで」 を、メモリの動きとセットで追っていきます。
たぶん最後に、「タブを閉じるのが正解じゃない場面」も見えてきます。
— PROLOGUE

大前提: 1 タブ = 1 プロセス

Chrome は 2008 年から「マルチプロセス」設計
素朴な疑問
タブってアプリ全体の中の "1 機能" じゃないの?

違いました。Chrome は 1 つのタブ = 1 つの独立したプロセス として扱っています。

OS から見ると、Chrome は 1 個のアプリじゃなくて、たくさんの小さいプロセスの集合。タブ 30 個なら、30 個以上のプロセスが同時に動いているイメージ。

これは マルチプロセス・アーキテクチャ という設計で、2008 年の Chrome 初代から採用されているもの。安定性とセキュリティのためにこうなっているらしいです。

[ 一般的なアプリ ]
┌────────────────┐
│ 1 プロセス     │
│ すべての機能   │
└────────────────┘

[ Chrome ]
┌──────────────────────────┐
│ Browser Process (本体)     │
│ ┌────────┐ ┌────────┐    │
│ │Renderer│ │Renderer│… │
│ │Tab A   │ │Tab B   │    │
│ └────────┘ └────────┘    │
│ ┌────────┐ ┌────────┐    │
│ │GPU     │ │Network │    │
│ └────────┘ └────────┘    │
└──────────────────────────┘
TERM
マルチプロセス・アーキテクチャ
機能をプロセス単位で分離する設計。1 つが落ちても他に影響しない(安定性)、互いのメモリを覗けない(セキュリティ)、並列実行できる(性能)の 3 大メリットがある。
— PROLOGUE (続き)

なぜわざわざ 分けてるのか?

分離のコストを払ってでも欲しいもの
1 プロセスにまとめた方がメモリは節約できる。でも Chrome は、あえて分けるコストを払っています。理由は 3 つ。
— 理由 01
安定性
1 つのタブが落ちても、他のタブ・ブラウザ本体は無事。「Aw Snap!」の画面を見たことあるかと思いますが、あれはそのタブだけが死んでる状態。
— 理由 02
セキュリティ
悪意のあるサイト A が、別タブで開いてる Gmail のメモリを覗けない。プロセスが分かれていれば、OS が物理的にメモリ空間を分離してくれる。
— 理由 03
並列性能
CPU の複数コアを活かして、タブごとに並列実行できる。1 つの重いタブが、他のタブの操作をブロックしない。
そして 2018 年からは Site Isolation という仕組みも入って、1 タブ内でもサイト単位で更にプロセスを分けるようになりました(後述)。

タブの 一生を辿る

01
誕生 + ボタンを押すと、新しいプロセスが立ち上がる
Process Spawn
02
読み込み URL を解決して、HTML/CSS/JS を取得・解析・描画
Network → Render
03
アクティブ 表示中。フルにメモリと CPU を使う状態
Active
04
休眠 バックグラウンドへ → 凍結 (Frozen) や破棄 (Discarded)
Page Lifecycle
05
× ボタンでプロセス終了、メモリ解放
Process Kill
— STEP 01 / 05

タブの誕生

+ を押した瞬間に、何が起きているか
素朴な疑問
+ を押すと、一瞬で新しいタブが出てくるけど、裏では?

+ ボタンを押すと、Chrome 本体 (Browser Process) が OS に「新しいプロセスを作って」と依頼します。

OS は新しいプロセスにメモリ空間を割り当てて、その中で Renderer Process と呼ばれる "タブ用のプロセス" が起動。中には V8(JS エンジン)Blink(HTML/CSS レンダリングエンジン)が入ってる。

空のタブでも、起動した瞬間に 30〜50 MB くらいメモリを使うらしいです。「中身ゼロ」じゃないんですね。

[ + ボタン押下 ]
       ↓
Browser Process が OS にお願い
       ↓
OS: 新しいメモリ空間を確保
       ↓
新しい Renderer Process 起動
       ┌──────────────┐
       │ ┌──────────┐ │
       │ │ V8       │ │ JS エンジン
       │ ├──────────┤ │
       │ │ Blink    │ │ レンダリング
       │ ├──────────┤ │
       │ │ DOM tree │ │ 空っぽ
       │ └──────────┘ │
       └──────────────┘
        ~30-50 MB
TERM
Renderer Process
タブごとに 1 つ作られる、Web ページを描画するためのプロセス。V8 (JS) + Blink (HTML/CSS) + DOM が入っている。「タブの中身」の正体。
— STEP 02 / 05

ページを読み込む

URL → DNS → HTML → 描画
素朴な疑問
URL を打つだけなのに、なぜ複数の "ぼぼぼ" って読み込まれてるの?

URL からページが表示されるまで、おおまかに 4 ステップ。

  • DNS 解決 — example.com → IP アドレスに変換
  • HTML 取得 — そのサーバーから HTML をダウンロード
  • 追加リソース取得 — HTML を読みながら CSS/JS/画像も取得
  • 描画 — DOM ツリー組み立て → ピクセルに変換

この間ずっと、Renderer Process はメモリにデータを溜め込みながら動いてます。Gmail のような重いサイトだと、ここで 300〜500 MB まで膨らむことも。

URL: https://example.com
       ↓
[ 1. DNS ] example.com = 203.0.113.5
       ↓
[ 2. HTTP ] GET / → HTML 取得
       ↓
[ 3. Parse ] HTML 解析
       ↓ <link> <script> <img> を発見
追加ダウンロード並列実行
       ↓
[ 4. Render ]
   DOM ツリー組み立て
   ↓
   レイアウト計算
   ↓
   ピクセルに描画
TERM
Blink (Rendering Engine)
HTML/CSS を解析して画面に描く Chrome のエンジン。Safari の WebKit から派生して、今は Chrome 独自に発展。Edge や Opera など多くのブラウザでも使われている。
— STEP 03 / 05

アクティブなタブの中

"1 タブ 1 プロセス" は、もう昔の話
素朴な疑問
タスクマネージャーを開くと、1 タブのはずなのに「Chrome」が何個も並んでるのは?

これが Site Isolation。Chrome 67 (2018年) からデフォルトで有効になった機能で、1 タブの中でも、サイトが違えばプロセスを分ける ようになりました。

例えば news.example.com を開くと、そのページに埋め込まれた YouTube 動画、Twitter ウィジェット、広告、解析タグ…がそれぞれ別プロセスに。1 タブで 5〜6 プロセス、ということも。

理由は Spectre 脆弱性。同じプロセスにいると、悪意あるサイトが他サイトのメモリを覗ける可能性があったので、物理的に分けることで防御している。

タブ: news.example.com

┌──────────────────────────┐
│ Renderer A: example.com  │  メイン
│ ┌────────────────────┐   │
│ │  <iframe ads.com>  │   │
│ └────────────────────┘   │
│ ┌────────────────────┐   │
│ │  <iframe yt.com>   │   │
│ └────────────────────┘   │
└──────────────────────────┘

↓ 実際の OS プロセス

[PID 100] example.com
[PID 101] ads.com  (iframe)
[PID 102] youtube.com (iframe)
[PID 103] analytics.com

→ メモリ +10〜15%
TERM
Site Isolation
サイト単位 (オリジン単位) でプロセスを分ける Chrome の仕組み。Spectre 攻撃などへの防御。代償として、メモリ使用量が 10-15% 増える。
— STEP 04 / 05

タブの "休眠状態"

バックグラウンドに行ったタブの運命
Chrome はタブを「表示中 or 表示してない」の 2 値じゃなくて、細かい状態を持っています。Page Lifecycle API という標準仕様。
— ACTIVE
表示中
フォアグラウンドで操作中。フルにメモリと CPU を使う。
300-500 MB
— PASSIVE
バックグラウンド
他のタブに切り替えた直後。まだ生きていて、JS も動く。
300-500 MB
— FROZEN
凍結
5 分以上未使用 → JS の実行が停止。メモリは保持。
~200 MB
— DISCARDED
破棄
プロセスごと終了。タブの "見た目" だけ残る。再アクセス時にリロード。
~0 MB
素朴な疑問
「あれ、このタブ更新かかった?」となるのはこれ?

そうみたいです。Discarded された後にクリックすると、タブはまだそこにあるけど、中身は最初からリロードされる。

Chrome 設定の Memory Saver モードがこれを積極的にやってくれる機能。一定時間使ってないタブを Discarded にして、メモリを返す。

TERM
Page Lifecycle API
Web 標準仕様。ブラウザがタブの状態を遷移させるための定義。開発者は freeze/resume イベントを使って、自分のサイトが凍結される前に状態を保存できる。
TIP
Memory Saver モード
chrome://settings/performance から有効化。使ってないタブを自動 Discard。Chrome 140 からは ML 予測で "戻る可能性が低いタブ" を狙い撃ち。
— STEP 05 / 05

タブの死

× ボタンを押した瞬間に何が起きるか
素朴な疑問
タブを閉じた瞬間、メモリってちゃんと返ってくるの?

× を押すと、Browser Process が OS にそのプロセスを kill するよう依頼。OS は、そのプロセスが使ってたメモリ空間を回収します。

これは 即座に・確実に 起きるみたいです。タブ閉じれば、そのタブ分のメモリは戻ってくる。30 タブ閉じれば 2〜4 GB 返ってきても不思議じゃない。

ただし、同じプロセスを共有してる他タブが残ってると、メモリ完全には返らないことも。Site Isolation のせいで、思ったほど解放されないケースもあるとか。

[ × ボタン押下 ]
       ↓
Browser Process が OS に依頼:
"kill PID 100"
       ↓
OS の動き:
   1. プロセスを停止
   2. メモリ空間を解放
   3. ファイルハンドル等を回収
       ↓
~ 数ms で完了

残ったもの:
   ・ブラウザの履歴
   ・Cookie / localStorage
   ・bfcache (もし対象なら)
TERM
bfcache (Back/Forward Cache)
「戻る」「進む」を高速化する仕組み。タブのメモリスナップショットを保持して、戻ったら一瞬で復元。閉じてはいないけど、メモリは消費し続ける。
— BONUS

では、タブ 30 個のメモリは?

タスクマネージャーを Shift+Esc で開いて見てみよう
1 タブのメモリ使用量、こんな感じで内訳ができてます。タブの種類による差がすごい。
~50 MB
空のタブ
about:blank。プロセス起動コストだけ。
~100 MB
普通の記事ページ
ニュースサイトとか、軽めのページ。
~300 MB
Gmail / Notion
JS で重い Web アプリ。
~500 MB+
Figma / Google Sheets
ヘビーな計算 / 描画系。
つまり タブ 30 個 = ~2-4 GB は普通。ここに拡張機能 (1 個 ~50 MB × 15 個 = 750 MB) も足されるので、Chrome が "重い" のは設計通りの動作と言える…。
Shift + Esc で Chrome 内蔵タスクマネージャーが開きます。タブごとの内訳が見られるので、覗いてみると面白いです。

タブは 1 つの独立した OS プロセス
だった。

— LIFE 01
誕生
+ を押すと OS に新規プロセス依頼。V8 + Blink + DOM が起動して、空でも 30-50 MB。
— LIFE 02
活動中
Site Isolation で、1 タブ内でもサイト別にプロセス分割。Spectre 対策、代償はメモリ +10-15%。
— LIFE 03
休眠・死
Page Lifecycle で Frozen / Discarded に遷移。× で kill → メモリ即返却。
— TAKEAWAY
Chrome は「あえてメモリを使って、安定性とセキュリティを買っている」設計。
— "タブを閉じる" のではなく "Discarded に任せる" が、たぶん現代的な使い方。

タブが プロセスだと知ると、
Chrome の "重さ" は
設計の代償 に見えてくる。

一番身近なアプリほど、
中身を覗くと面白い仕組みが隠れてた
— Shift+Esc、ぜひ開いてみてください。
END. ご清聴ありがとうございました
1 / 13