1-2. プログラムが動く仕組み
このセクションで学ぶこと
Section titled “このセクションで学ぶこと”- ソースコードが実行されるまでの流れ
- コンパイルとインタプリタの違い
- スタックとヒープの仕組み
- スレッドとプロセスの違い
1. ソースコードから実行まで
Section titled “1. ソースコードから実行まで”プログラマーが書く「ソースコード」は、そのままではCPUは理解できない。CPUが理解できるのは 機械語(マシン語) のみ。
ソースコード → 変換 → 機械語 → CPUが実行(人間が読める) (0と1の羅列)変換の2つの方法
Section titled “変換の2つの方法”コンパイル方式
Section titled “コンパイル方式”実行前にソースコード全体を機械語に変換する方式。
ソースコード │ ▼ コンパイラ(翻訳ツール)機械語ファイル(実行ファイル) │ ▼ 実行- 代表言語:C, C++, Rust, Java(バイトコードに変換)
- メリット:実行が速い(変換済みのため)
- デメリット:実行前にコンパイルが必要。エラーも事前にわかる
インタプリタ方式
Section titled “インタプリタ方式”コードを1行ずつ読みながらその場で実行する方式。
ソースコード │ ▼ インタプリタ(逐次実行) 実行(行ごと)- 代表言語:Python, Ruby, JavaScript(ブラウザやNode.jsで実行)
- メリット:すぐに実行できる。対話的な操作も可能
- デメリット:コンパイル方式に比べて実行が遅い
Javaは特殊なケース
Section titled “Javaは特殊なケース”Javaは「コンパイル」と「インタプリタ」の中間的な方式を採用している。
Javaソースコード(.java) │ ▼ javac(Javaコンパイラ)バイトコード(.class) ← 機械語ではなく中間コード │ ▼ JVM(Java Virtual Machine)が実行- バイトコードはOSに依存しない → どのOS上でも同じコードが動く(Write Once, Run Anywhere)
- JVMがバイトコードを各OSの機械語に変換しながら実行する
2. スタックとヒープ
Section titled “2. スタックとヒープ”プログラムが実行される際、メモリは主に2つの領域に分かれて使われる。
メモリの構造
┌──────────────────┐ ← 高アドレス│ スタック │ ← 関数の呼び出しや│ (Stack) │ ローカル変数を保存│ ││ ↓ 伸びる ││ ││ ↑ 伸びる ││ ││ ヒープ │ ← 動的に確保するデータ│ (Heap) │├──────────────────┤│ 静的領域 │ ← グローバル変数など├──────────────────┤│ コード領域 │ ← プログラム本体└──────────────────┘ ← 低アドレススタック(Stack)
Section titled “スタック(Stack)”- 特徴:後入れ先出し(LIFO: Last In, First Out)の構造
- 用途:関数の呼び出し情報・ローカル変数
- 管理:自動的に確保・解放される
- サイズ:小さい(通常数MB)
// 関数呼び出しのイメージfunction main() { // スタックに main のフレームを積む int x = 10; greet(); // スタックに greet のフレームを積む} // main のフレームが取り除かれる
function greet() { String msg = "Hello"; // スタックに msg を積む} // greet のフレームが取り除かれるスタックオーバーフロー(StackOverflow)は、関数が無限に呼び出され続けてスタックが満杯になったときに発生する。
ヒープ(Heap)
Section titled “ヒープ(Heap)”- 特徴:自由に確保・解放できる
- 用途:実行時に動的に作成されるオブジェクト
- 管理:プログラムまたはGCが管理する
- サイズ:大きい(GBオーダーも可能)
// Java の例String name = new String("Alice");// "Alice" というオブジェクトはヒープに確保される// Java ではGC(ガベージコレクタ)が自動的に解放してくれるガベージコレクション(GC)
Section titled “ガベージコレクション(GC)”JavaやJavaScriptなどは ガベージコレクタ が不要になったメモリを自動的に解放する。 C/C++ではプログラマが手動でメモリを解放する必要があり、解放忘れると メモリリーク が発生する。
3. プロセスとスレッド
Section titled “3. プロセスとスレッド”プロセス(Process)
Section titled “プロセス(Process)”OSが管理するプログラムの実行単位。
- それぞれ独立したメモリ空間を持つ
- プロセス同士はメモリを共有しない(直接干渉できない)
- 例:ブラウザ、エディタ、ターミナルは別々のプロセス
OSが管理するプロセス一覧
PID プロセス名1234 Chrome5678 VSCode9012 Terminalスレッド(Thread)
Section titled “スレッド(Thread)”プロセスの中でさらに並行して動く実行単位。
- 同じプロセス内のスレッドはメモリを共有する
- 複数スレッドで同時に処理を進められる(並列処理)
プロセス(Chrome)├── スレッド1: タブのレンダリング├── スレッド2: ネットワーク通信└── スレッド3: JavaScriptの実行シングルスレッド vs マルチスレッド
Section titled “シングルスレッド vs マルチスレッド”| 種類 | 特徴 | 代表 |
|---|---|---|
| シングルスレッド | 1つずつ処理。シンプルで安全 | JavaScript(メインスレッド) |
| マルチスレッド | 複数の処理を同時進行。高速だが複雑 | Java, C++ |
JavaScriptの非同期処理
Section titled “JavaScriptの非同期処理”JavaScriptはシングルスレッドだが、イベントループの仕組みで非同期処理(時間のかかる処理を待っている間に別の処理を進める)を実現している。
console.log("1番目");
setTimeout(() => { console.log("3番目(1秒後)");}, 1000);
console.log("2番目");
// 出力:// 1番目// 2番目// 3番目(1秒後)4. プログラムが実行されるまでの全体像
Section titled “4. プログラムが実行されるまでの全体像”1. ソースコードを書く(.java / .js など) │ ▼2. コンパイル or そのまま(言語による) │ ▼3. OSがプログラムを読み込みプロセスを作成 │ ▼4. OSがメモリ(スタック・ヒープ)を確保 │ ▼5. CPUがコードを1命令ずつ実行 │ ▼6. 処理が終わるとOSがプロセスを終了し、メモリを解放| キーワード | 説明 |
|---|---|
| コンパイル | 実行前にソースコードを機械語に変換する |
| インタプリタ | コードを1行ずつ実行する |
| バイトコード | JavaのJVM用の中間コード |
| スタック | 関数呼び出しやローカル変数を保存するメモリ領域 |
| ヒープ | 動的に確保するオブジェクトを保存するメモリ領域 |
| GC | 不要になったメモリを自動解放する仕組み |
| プロセス | OSが管理するプログラムの実行単位 |
| スレッド | プロセス内で並行して動く処理の単位 |
次のステップ
Section titled “次のステップ”演習問題 に取り組んで理解を確認しよう。
理解できたら 1-3. コマンドライン基礎 へ進もう。