Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ナカナカピエロ

 ナカナカピエロ

このスライドはJavaプログラミングを学ぶ前に知っておくべき、Javaの処理系の話やコンピュータの内部のプログラムの動きについて説明したものです。

ナカナカピエロ

September 16, 2023
Tweet

Other Decks in Programming

Transcript

  1. 2 コンピュータとは何か 何らかの手段で入力されたものを処理し結果を出力する機械 【入力】 ・キーボート ・マウス ・タッチパネル ・ファイル USBメモリや ハードディスク

    に記録 などなど多数 【出力】 ・画面 ・プリンタ ・ファイル USBメモリや ハードディスク に記録 などなど多数 【処理】 でもコンピュータの中で何が行われているかはよく分からない。 ブラックボックス!
  2. 4 OSの役割とプログラムとの関係 OSは全ての機器、アプリケーションを管理しているシステム基盤プログラム。 アプリケーションプログラムはOS上で動いている。 【入力機器】 ・キーボート ・マウス ・タッチパネル ・ファイル USBメモリや

    ハードディスク に記録 などなど多数 【出力機器】 ・画面 ・プリンタ ・ファイル USBメモリや ハードディスク に記録 などなど多数 CPU、メモリ、ネットワーク、入力機器、出力機器など全ての機器 OS (Operating System)プログラム アプリケーション プログラム アプリケーション プログラム アプリケーション プログラム ・・・・・・・
  3. 5 プログラムはどう動くか? プログラムはコンパイラで翻訳されて動くものとインタプリタで逐次動的に動くものがある。 OS (Operating System)プログラム アプリケーションプログラム (実行可能モジュール) 中身はマシンコードが入っている コンパイラ・ソフトウェア

    ソースプログラムからマシンコード に翻訳して変換する ソースプログラム C言語やC++言語などで書かれた プログラム インタプリタ ソースプログラムからプログラムを 読み取り一行ずつ実行する (内部的には疑似的な バイトコードに変換しながら実行) ソースプログラム PythonやRubyなどで書かれた プログラム 【インタプリタ】 【コンパイラ】
  4. 6 コンパイラ vs インタプリタ コンパイラとインタプリタにはメリット・デメリットがある コンパイラ インタプリタ メリット 実行速度が速い プログラムをただちに実行できる

    OSが違っても動作する デメリット いちいちコンパイルが面倒 OSが違うと動かない 実行速度が遅い 特徴 大規模で計算量の多いシステムを 構成するのに適している 小規模のシステムや比較的単純な プログラムを書くのに適している 近年はコンピュータの性能が著しく進歩し インタプリタ型のプログラミング言語が活用されている場面も 多い
  5. 7 Javaプログラムはどう動くか? プログラムはJava VM(Virtual Machine)が動作するOS上でならどこでも動作する。 Write once, run anywhere バイトコードモジュール(.class)

    Javaコンパイラ Javaソースプログラム(.java) JavaVM(仮想マシン) Windows OS Mac OS Linux OS ・・・・・・・ JavaVM(仮想マシン) JavaVM(仮想マシン) どこでも動作する ある意味良いとこ取り
  6. 8 Javaの高速化技術(JITコンパイラ) さらにJava VM(Virtual Machine)はプログラムを高速化するために内部で JIT(Just In Time)コンパイラを持っている。 バイトコードモジュール(.class) JavaVM(仮想マシン)

    OS インタプリタ バイトコードを解釈 しながら実行する。 JITコンパイラ よく実行されるバイトコードを マシンコードに翻訳する。 マシンコード
  7. 10 コンピュータが扱うデータの単位を知ろう~ビットとバイト~ コンピュータが扱う情報の最小単位はビット (0または1)。 ビットを扱うときには、2進数を用いる。 (例) 0b001101 -> 10進数に変換 2^3*1+2^2*1+2^1*0+1=13

    もっと大きい単位でデータを扱いたい 8ビットを1バイトという単位でデータを扱う。0~15(2^4-1)の値を表現できる。 バイトを扱うときには、16進数を用いる。 16進表記は、0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, Fで表現する。 (例) 0xFB -> 10進数に変換 16*15+11=251 良く使用されるバイト数 バイト数 ビット数 1バイト 8ビット 2バイト 16ビット 4バイト 32ビット 8バイト 64ビット 良く使用される単位 単位 バイト数 1K(キロ)バイト 1024バイト 1M(メガ)バイト 1024Kバイト 1G(ギガ)バイト 1024Mバイト 1T(テラ)バイト 1024Gバイト
  8. 11 CPUについて知ろう CPU(Central Processing Unit)はコンピュータの頭脳。 でもCPUは基本的な命令しか実行できない。 しかしCPUは高速にその命令を実行する。 (例) 周波数が1GHzで1命令1クロックで処理するCPUだと 1秒間に理論的には

    1000*1000*1000=1,000,000,000命令を実行できる CPUが実行できる命令の例 デュアルコアならCPU2個分、クアッドコアならCPU4個分の 処理が並列に実行可能。 クロック周波数はコンピュータの同期を とるための信号のこと。 周波数はコンピュータのメトロノーム。 CPUが速いからと言ってプログラムが 早く動くとは限らない。何故か?
  9. 14 Javaのデータアクセス 0x4000000 0x4000004 0x4000008 0x4000010 0x4000018 0x4000020 Javaでは、データを直接扱う基本型 (整数型、浮動小数点型、文字型など)と

    アドレス経由でデータを扱う参照型(クラス型、配列型、String型など)がある。 Javaでは参照型のアドレス値は直接操作することはできないようになっている。 よって不正アドレス参照などの実行時エラーは基本的には発生しない。(安全) 整数型(int)の変数 x、yには 値が入っている 25 25 x y x==yはtrue 文字列型Stringの変数 x、yには 参照値が入っている 0xXXXXXXXX x y x==yはfalseになることが ある 値の比較を行いたいときは x.equals(y)を使う。 “abc” 0xYYYYYYYY “abc”
  10. 15 プログラムはどのように実行されているか プログラムは簡単に言えば、以下の2つの記憶域で管理されて実行されている。 プログラムカウンタ(pc) 現在のプログラムの実行命令のアドレス スタックポインタ(sp) プログラムの状態を管理しているメモリのアドレス main関数 { 実行文1

    実行文2 func1(); 実行文8 } func1関数 { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } この例では実行文1,2,3,4,5,6,7,8の順で実行される。 現在、実行文6を実行中の状態 前のフレームアドレス : 戻りアドレス(pcを退避) func2関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし プログラムはmain関数から始まる
  11. 16 プログラムはどのように実行されているか(アニメーション01) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレーム なし 0x0 未退避
  12. 17 プログラムはどのように実行されているか(アニメーション02) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレーム なし 0x0 未退避
  13. 18 プログラムはどのように実行されているか(アニメーション03) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレーム なし 0x0 未退避
  14. 19 プログラムはどのように実行されているか(アニメーション04) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  15. 20 プログラムはどのように実行されているか(アニメーション05) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  16. 21 プログラムはどのように実行されているか(アニメーション06) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  17. 22 プログラムはどのように実行されているか(アニメーション07) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func2関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  18. 23 プログラムはどのように実行されているか(アニメーション08) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func2関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  19. 24 プログラムはどのように実行されているか(アニメーション09) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func2関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  20. 25 プログラムはどのように実行されているか(アニメーション10) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  21. 26 プログラムはどのように実行されているか(アニメーション11) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 未退避 0x0 前のフレーム なし
  22. 27 プログラムはどのように実行されているか(アニメーション12) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレーム なし
  23. 28 プログラムはどのように実行されているか(アニメーション13) main関数 { 実行文1 実行文2 func1(); 実行文8 } func1関数

    { 実行文3 実行文4 func2(); 実行文7 } func2関数 { 実行文5 実行文6 } 前のフレームアドレス : 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレーム なし 0x0 未退避 プログラムが終了した
  24. 30 データはどのように管理されているか(アニメーション01) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス null 0 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の 戻り値を格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域
  25. 31 データはどのように管理されているか(アニメーション02) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス null 0 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の 戻り値を格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域
  26. 32 データはどのように管理されているか(アニメーション03) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス null 10 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の 戻り値を格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域
  27. 33 データはどのように管理されているか(アニメーション04) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス 10 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の 戻り値を格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域 0 0 0
  28. 34 データはどのように管理されているか(アニメーション05) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス 10 - 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス 10 - 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の戻り値を 格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域 0 0 0 関数の戻り値を 格納する領域 変数 xp 変数 ary
  29. 35 データはどのように管理されているか(アニメーション06) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス 10 - 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス 10 - 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の戻り値を 格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域 0 0 0 関数の戻り値を 格納する領域 変数 xp 変数 ary
  30. 36 データはどのように管理されているか(アニメーション07) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス 20 - 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス 10 - 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の戻り値を 格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域 0 0 0 関数の戻り値を 格納する領域 変数 xp 変数 ary
  31. 37 データはどのように管理されているか(アニメーション08) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス 20 - 戻りアドレス(pcを退避) func1関数スタックフレーム 前のフレームアドレス 10 - 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の戻り値を 格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域 0 5 0 関数の戻り値を 格納する領域 変数 xp 変数 ary
  32. 38 データはどのように管理されているか(アニメーション09) main関数 { int x=10; int[]ary =new int[3]; func1(x,

    ary); } func1(int xp, int [] aryp) { xp=20; ary[1]=5; } 前のフレームアドレス 10 - 戻りアドレス(pcを退避) main関数スタックフレーム pc sp 0x0 前のフレームなし 0x0 未退避 関数の戻り値を 格納する領域 変数 x 変数 ary 静的領域 スタック領域 ヒープ領域 0 5 0 プログラムが終了した