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

オブジェクトライフサイクルとメモリ管理を学ぼう / OOC 2020

Akira Morikawa
February 15, 2020

オブジェクトライフサイクルとメモリ管理を学ぼう / OOC 2020

Akira Morikawa

February 15, 2020
Tweet

More Decks by Akira Morikawa

Other Decks in Technology

Transcript

  1. Lifecycle
    #ooc_2020 #ooc_b

    View Slide

  2. View Slide

  3. Akira

    View Slide

  4. View Slide

  5. View Slide

  6. The inside of

    View Slide

  7. 7
    本セッションで説明する内容は、簡略表現が随所に含まれます。
    できる限り正確性に留意して記載していますが、
    その内容について信頼性をなんら保証しませんのでご了承ください。

    View Slide

  8. 8
    目次
    Table of Content
    Memory Management
    Object Internals
    Garbage Collection
    Regression
    1
    2
    3
    4

    View Slide

  9. #ooc_2020 #ooc_b
    メモリ管理の実装
    9
    Memory Management

    View Slide

  10. #ooc_2020 #ooc_b 10
    new Object ();
    この1行を起点にして、
    メモリはどのように使われるだろう?

    View Slide

  11. #ooc_2020 #ooc_b 11
    CPU
    Register
    Processor
    RAM
    BUS
    ( Front Side Bus )
    ( Cache )
    LOAD
    STORE
    Page
    CPU/RAM の動作
    ● CPU はレジスタに内部データを保管
    ○ x64 の汎用レジスタは 64bit × 16
    ○ 最近の CPU は複数段キャッシュ
    ● CPU/BUS/RAM で動作周波数が異なる
    ○ CPU 外との通信は相対的に遅い
    ○ データ読書単位=レジスタサイズ

    View Slide

  12. #ooc_2020 #ooc_b 12
    new Object ();
    格納先候補 実格納先
    変換テーブル

    View Slide

  13. #ooc_2020 #ooc_b 13
    アドレス変換
    Address Translation
    new Object ();
    論理アドレス 物理アドレス
    ページテーブル
    ※リニアアドレス省略

    View Slide

  14. #ooc_2020 #ooc_b
    ( 最大メモリ 256 TB )
    14
    アドレス変換
    Address Translation
    x64 ページテーブル
    PML4
    ( Page Map Level 4 Table )
    PDPT
    ( Page Directory Pointer Table )
    PDE
    ( Page Directory Entry )
    PTE
    ( Page Table Entry )
    4 KB
    2 MB
    1 GB 48 bit addressing

    View Slide

  15. #ooc_2020 #ooc_b
    Page ( 4 KB )
    15
    アドレス変換
    Address Translation
    PML4 PDPT PDE PTE
    64bit ( 48bit ) Virtual Address
    47 0
    11
    20
    29
    38
    CR3 Register

    View Slide

  16. #ooc_2020 #ooc_b 16
    アドレス変換
    Address Translation
    論理アドレス
    MMU
    Memory
    Management
    Unit
    TLB
    Translation
    Look-aside
    Buffer
    物理アドレス
    ● アドレス変換は CPU 内の専用ハードウェアが行う
    ● アドレス変換情報は TLB によってキャッシュされる
    ● TLB にキャッシュがない場合はページテーブルを参照する(ページウォーク)
    DDR
    Controller

    View Slide

  17. #ooc_2020 #ooc_b 17
    アドレス変換
    Address Translation
    x64 ( AMD64 / Intel64 ) アーキテクチャにおいて、
    ● OS <-> RAM 間は 64bit 単位で読み書きされる
    ● メモリアドレスは 48bit ( 最大 256TB ) で表されている
    ● メモリ要求量に応じて 4 KB / 2 MB / 1 GB ごとに区切られたページが確保される
    ● 仮想~物理アドレスの対応はページテーブルで管理される
    ● 頻繁に使われるアドレスは TLB ( Translation Look-aside Buffer ) にキャッシュされる
    ● ページテーブルは OS* が定義してメモリに格納するが、動作は CPU の機構
    * GDT ( Global Descriptor Table ) の一部として定義される

    View Slide

  18. #ooc_2020 #ooc_b 18
    メモリアロケータ
    Memory Allocator
    メモリアロケータ
    プログラム OS ~ CPU

    View Slide

  19. #ooc_2020 #ooc_b 19
    メモリアロケータ
    Memory Allocator
    glibc malloc()
    プログラム
    Main Arena
    Arena
    chunk
    chunk
    chunk
    fastbins[]
    bins[]
    ※かなり簡略化しています
    top
    next

    View Slide

  20. #ooc_2020 #ooc_b 20
    メモリアロケータ
    Memory Allocator
    glibc malloc()
    ● 確保したいメモリサイズに応じて自動で最適なサイズを割り当てる
    ● 確保したいメモリサイズごとに異なる領域 ( fastbins, bins ) をもつ
    ○ fastbins <= 160 bytes
    ○ bins > 160 bytes
    ● 大きなメモリ ( >= M_MMAP_THRESHOLD ) は mmap 命令で確保する
    ● free しても内部的にはキャッシュのため解放されない場合がある
    ● chunk 単位でメモリを確保・管理する
    ● chunk は 8 バイトでアラインメントされている
    ● 詳しい実装は この辺り を参考に

    View Slide

  21. #ooc_2020 #ooc_b 21
    メモリアロケータ
    Memory Allocator
    有名なメモリアロケータ
    ● glibc malloc
    ● TCmalloc ( Google )
    ● mimalloc ( Microsoft )
    ● jemalloc
    ● nedmalloc

    View Slide

  22. #ooc_2020 #ooc_b 22
    アラインメント
    Alignment
    型 メモリ(バイト)
    short 2
    int 4
    float 4
    double 8
    char 1
    一般的なデータ型のメモリ使用量
    struct Person {
    char age; /
    / 1 byte
    int gender; /
    / 4 bytes
    short height; /
    / 2 bytes
    double weight; /
    / 8 bytes
    };
    実際は何バイト使われる?

    View Slide

  23. #ooc_2020 #ooc_b
    0 ( bytes ) 8 16 24
    23
    アラインメント
    Memory Alignment
    未使用領域
    アライメント ( Alignment )
    メモリ使用境界をキャッシュライン(アクセスに最適なサイズ境界)にあわせること
    ● アクセスに無駄がなく高速に読み書きできる
    ● CPUによってはアラインメント違反はエラーになる
    ● 未使用領域が発生する

    View Slide

  24. #ooc_2020 #ooc_b
    height
    24
    アラインメント
    Alignment
    gender weight
    age
    0 4 8 16
    1
    アライメント最適化
    ● 各言語コンパイラがフィールド並び順を最適化するなど工夫している
    ● 最適化の限界はキャッシュライン+高級言語の仕様次第

    View Slide

  25. #ooc_2020 #ooc_b 25
    メモリの分類
    Stack and Heap
    BSS DATA TEXT
    基本的なメモリの分類
    スタック
    ● 確保・解放が高速
    ● 寿命が短い ( LIFO )
    ● サイズが小さい
    ○ ulimit -s ( Default 8MB )
    ヒープ
    ● 確保・解放が低速
    ● 寿命が自由
    ● サイズが大きい
    Shared Heap
    Stack

    View Slide

  26. #ooc_2020 #ooc_b 26
    スタックとヒープ
    Stack and Heap
    参照型変数
    Object b
    ローカル変数
    int c = 1;
    ローカル変数
    int d = 2;
    Object() 実体
    Object() 実体
    参照型変数
    Object a
    スタック ヒープ
    値をもつ

    View Slide

  27. #ooc_2020 #ooc_b 27
    スタックとヒープ
    Stack and Heap
    f2()
    int data = 0;
    f1()
    int data = 0;
    global
    f3()
    int data = 0;
    コールスタック ( Call Stack )
    関数用に確保されたエリアで、
    「関数スタック」ともいう。
    呼び出し順に積み上げられて、
    リターン時に自動破棄される。
    ● ローカル変数/引数
    ● RBP
    ● リターンアドレス
    格納する箱の単位を「スタック
    フレーム」という。
    global f1() f2() f3()
    呼び出し順序

    View Slide

  28. #ooc_2020 #ooc_b 28
    Stack and Heap
    スタックとヒープ
    hoge
    fuga
    Arena
    Arena
    ヒープ ( Heap )
    いつでも自由に数KB~数GB単位の
    大きなメモリ領域を確保し、必要な
    時間だけ占有できる。
    使用後は必ず誰かが解放する。

    View Slide

  29. #ooc_2020 #ooc_b 29
    まとめ
    Conclusion
    ● CPU 内で一度に処理できるデータは 64bit ( x64 )
    ● メモリとの読み書きを頻繁に繰り返している
    ○ 高速に保つため CPU 内で n 次キャッシュをもつ
    ○ アクセス速度はバスクロック/メモリクロックに依存する
    ● オブジェクトで管理されるメモリ領域はアラインメントされる
    ● 引数やローカル変数は高速なスタック領域に確保される
    ● グローバル変数など長期間使用する場合はヒープ領域に確保される
    ● 大きなオブジェクトのメモリ確保は相対的に重い

    View Slide

  30. #ooc_2020 #ooc_b 30
    Object Internals
    オブジェクトの正体

    View Slide

  31. #ooc_2020 #ooc_b 31
    new Object ();
    オブジェクトの正体にせまろう

    View Slide

  32. #ooc_2020 #ooc_b 32
    オブジェクトの正体は?
    Shape of object
    オブジェクト実体
    オブジェクトヘッダ 言語ごとの実装は?
    new Object ();

    View Slide

  33. #ooc_2020 #ooc_b 33
    PHP 5.x
    Shape of Object
    ZVAL構造体 [ php-src/Zend/zend.h#L334 ]
    項目 内容
    refcount 参照カウンタ
    type 型を示す文字列 ( Type specifier )
    is_ref 参照集合かどうかを判定するBool値

    View Slide

  34. #ooc_2020 #ooc_b 34
    PHP 7.x
    Shape of Object
    ZVAL構造体 [ php-src/Zend/zend_types.h#L196 ]

    View Slide

  35. #ooc_2020 #ooc_b
    $ php hoge.php
    name: (interned, is_ref=0)='@ariaki4dev'
    hello: (refcount=1, is_ref=0)='Hello, @ariaki4dev'
    35
    PHP 7.x
    Shape of Object
    ZVALの内容確認(※要xdebug)
    ● interned:文字列がインターン化された状態
    ● refcount:参照カウンタ
    ● is_ref:参照の有無

    View Slide

  36. #ooc_2020 #ooc_b 36
    PHP 7.x
    Shape of Object
    0
    0
    0
    a: (interned, is_ref=0)='test'
    b: (refcount=0, is_ref=0)=1234
    c: (refcount=2, is_ref=0)=array
    ( 0 => (interned, is_ref=0)='a',
    1 => (interned, is_ref=0)='b',
    2 => (interned, is_ref=0)='c' )
    インターン化
    同じ文字列を共通領域に保管し、個別に
    メモリを確保せず参照する。
    数値など他の型は対象外。

    View Slide

  37. #ooc_2020 #ooc_b
    $ php hoge.php
    name: (refcount=2, is_ref=1)='@ariaki4dev'
    account: (refcount=2, is_ref=1)='@ariaki4dev'
    37
    PHP 7.x
    Shape of Object
    ZVALの内容確認(※要xdebug)

    View Slide

  38. #ooc_2020 #ooc_b 38
    参照カウンタ
    Reference Counter
    $name
    $account
    “@ariaki4dev”
    refcount = 2

    View Slide

  39. #ooc_2020 #ooc_b 39
    参照カウンタ
    Reference Counter
    $name
    $account
    refcount = 0
    削除 ( GC ) 対象

    View Slide

  40. #ooc_2020 #ooc_b 40
    参照渡しと値渡し
    Call by Reference, Call by Variables
    $var_1
    $var_2
    $var_1
    $var_2
    参照渡し 値渡し

    View Slide

  41. #ooc_2020 #ooc_b 41
    コピーオンライト
    Copy-On-Write
    ● $ar1 → $ar2 にコピーされた時点では $ar2 のメモリは確保されない
    ● $ar2[0] がセットされた時点で値が複製 ( Copy-on-Write ) される
    ● 参照カウンタをもちいて refcount > 1 の場合に複製を実行する

    View Slide

  42. #ooc_2020 #ooc_b 42
    コピーオンライト
    Copy-On-Write
    0
    0
    376
    0
    コピーされた!

    View Slide

  43. #ooc_2020 #ooc_b 43
    PHP 7.x
    Shape of Object
    配列をいじめる(※要xdebug)
    0
    376
    376
    696 8 個ごとにメモリを追加確保している?!
    スタックから追い出された?!

    View Slide

  44. #ooc_2020 #ooc_b 44
    PHP 7.x
    Shape of Object
    オブジェクトをいじめる(※要xdebug)
    40
    96
    a: (refcount=1, is_ref=0)=class stdClass { }
    b: (refcount=1, is_ref=0)=class stdClass { }

    View Slide

  45. #ooc_2020 #ooc_b 45
    PHP 7.x
    Shape of Object
    オブジェクトをいじめる(※要xdebug)
    416
    416

    View Slide

  46. #ooc_2020 #ooc_b 46
    PHP 7.x
    Shape of Object
    オブジェクトをいじめる(※要xdebug)
    40
    40
    40

    View Slide

  47. #ooc_2020 #ooc_b 47
    PHP 7.x
    Shape of Object
    オブジェクトをいじめる(※要xdebug)
    56
    80
    96
    オーバーライドでメモリを別途確保してる

    View Slide

  48. #ooc_2020 #ooc_b 48
    PHP 7.x
    Shape of Object
    オブジェクトをいじめる(※要xdebug)
    100 万回継承した結果
    ● 使用メモリは変わらず 40 バイト
    ● ルートクラスの継承を確認できた
    ● 重かった(手元の PC で 8 秒位)

    View Slide

  49. #ooc_2020 #ooc_b 49
    Java VM
    Shape of Object
    Object Header ( 128bit )
    unused
    (25)
    thread
    (54)
    ptr_to_lock_record (62)
    ptr_to_heavyweight_monitor (62)
    OOP to metadata object
    OOP to metadata object
    OOP to metadata object
    OOP to metadata object
    OOP to metadata object
    Normal
    Biased
    Lightweight Locked
    Heavyweight Locked
    Marked for GC
    ( State )
    Mark Word ( 64bit )
    lock
    (2)
    lock
    (2)
    lock
    (2)
    lock
    (2)
    lock
    (2)
    epoch
    (2)
    unused
    (1)
    age
    (4)
    biased_lock
    (1)
    Klass Word
    ( 64bit )
    unused
    (1)
    age
    (4)
    biased_lock
    (1)
    identity_hashcode
    (31)
    Java x64 ヘッダ構造

    View Slide

  50. #ooc_2020 #ooc_b 50
    Java VM
    Shape of Object
    オブジェクトロックの種類
    ● Biased Lock
    ○ 単一スレッドがロックを占有 → 他スレッドから revoke ( Stop the World )
    ○ Java 6 以降で標準採用
    ● Lightweight Lock ( thin lock )
    ○ CAS ( Compare-and-Swap ) を用いたロック
    ○ 楽観的 ( optimistic ) ロック
    ● Heavyweight Lock ( fat lock )
    ○ OS のロック関数 ( pthread_mutex_lock) を用いたロック
    ○ 悲観的 ( pessimistic ) ロック

    View Slide

  51. #ooc_2020 #ooc_b 51
    Java VM
    Shape of Object
    悲観的ロック
    ( Pessimistic Lock )
    楽観的ロック
    ( Optimistic Lock )

    View Slide

  52. #ooc_2020 #ooc_b 52
    Java VM
    Shape of Object
    -XX : UseCompressedOops
    ● Java 6 以降、標準で有効になっている
    ● Klass Word を 32bit に圧縮する
    ● 手動で無効にすることもできる
    ● -Xmx32767m ( 32 GB ) 以上の場合、自動で無効になる
    ○ 大量メモリ割当が非効率といわれる原因のひとつ

    View Slide

  53. #ooc_2020 #ooc_b 53
    Java VM
    Shape of Object
    オブジェクトのメモリ配置
    ● すべてのオブジェクトは 8 バイト境界に配置される
    ● クラス変数は次のように並び替えられる
    ○ long, double → int, float → char, short → byte, boolean → 参照型
    ● 変数はそれぞれのバイト境界に配置される
    ● 階層の異なるクラスのフィールドは混合配置しない(親クラス→子クラス)
    ● 親クラスの最終フィールド後は 4 バイト境界にあわせる
    ● 子クラスの先頭フィールドが long, double かつ親クラスが 8 バイト境界以外の場合、
    節約のため他の型を先頭に配置する

    View Slide

  54. #ooc_2020 #ooc_b 54
    Java VM
    Shape of Object
    省メモリ戦略
    ● 参照型をできる限り減らす
    ○ String → char[]
    ○ プリミティブ型にする(例:Boolean → boolean )
    ● 大量のフラグを BitSet へ
    ● コレクションを減らす ( HashSet, HashMap, etc. )
    ● Generics 等による AutoBoxing に気をつける
    ● 省メモリライブラリを使用する
    ○ FastUtil / Eclipse Collections / hppc / Koloboke / Trove / など

    View Slide

  55. #ooc_2020 #ooc_b 55
    Java VM
    Shape of Object
    メモリ使用量の計測
    ● Instrumentation.getObjectSize(object)
    ● Runtime.getRuntime().totalMemory() / freeMemory()
    ● RamUsageEstimator.sizeOf() / hppc
    ● jstat

    View Slide

  56. #ooc_2020 #ooc_b 56
    Java VM
    Shape of Object
    JOL ( Java Object Layout ) - http:/
    /openjdk.java.net/projects/code-tools/jol/
    $ java -jar jol-cli/target/jol-cli.jar footprint java.util.Hashtable
    Running 64-bit HotSpot VM.
    Using compressed oop with 3-bit shift.
    Using compressed klass with 3-bit shift.
    Objects are 8 bytes aligned.
    Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
    Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
    java.util.Hashtable instance footprint:
    COUNT AVG SUM DESCRIPTION
    1 64 64 [Ljava.util.Hashtable$Entry;
    1 48 48 java.util.Hashtable
    2 112 (total)

    View Slide

  57. #ooc_2020 #ooc_b 57
    Java VM
    Shape of Object
    Header
    boxes[0]
    boxes[1]
    width
    Header
    height
    width
    Header
    height
    現在の配列構造
    無駄なヘッダ

    View Slide

  58. #ooc_2020 #ooc_b 58
    Java VM
    Shape of Object
    Header
    boxes[0]
    boxes[1]
    width
    height
    width
    height
    理想の配列構造
    boxes[2]
    width
    height
    Project Valhalla
    Value Types
    プリミティブ型と同じ挙動をす
    る任意の型を定義できる
    Generic Specialization
    ジェネリクスに対しプリミティ
    ブ型引数によるインスタンス化
    をサポートする
    https:/
    /openjdk.java.net/projects/valhalla

    View Slide

  59. #ooc_2020 #ooc_b 59
    Golang
    Shape of Object
    Golang のメモリ割り当て
    ● コンパイラが判断して自動的にスタック/ヒープを振り分ける
    ○ 基本的にはスタックを優先して使い、開発者が割当先を気にする必要はない
    ○ newしてもメソッド内で完結するものはスタック割当
    ○ ローカル変数のポインタを外に持ち出す場合はヒープ割当
    ○ どちらに振り分けられるかはビルドオプション ( -gcflags -m ) で確認できる
    ● メモリ管理には TCMalloc ( Google ) を使っている
    ○ 32KB 以下は個別管理、超えるものは共有管理
    ● goroutine は標準で 2KB のスタック を確保する
    ○ 必要に応じてスタックサイズが拡張される
    ○ スタックプールを用いて、未使用のスタックをキャッシュする

    View Slide

  60. #ooc_2020 #ooc_b 60
    まとめ
    Conclusion
    ● メモリ確保や使用方法は、それぞれ言語によって最適化されている
    ● クラスが階層化する場合、レイヤごとに属性が保持される
    ● オブジェクトヘッダ仕様は言語の設計思想が強く反映される
    ● オブジェクトの振る舞いやその理由を調べるのは楽しい

    View Slide

  61. #ooc_2020 #ooc_b 61
    Garbage Collection
    GC 理論と実装

    View Slide

  62. #ooc_2020 #ooc_b 62
    Garbage Collection
    Overview
    GC ( Garbage Collection )
    ● 不要になったメモリ領域を自動で回収する仕組み
    ○ それまではメモリ管理はすべて手動(確保~使用~解放)だった
    ○ 手動管理はあまりにも煩雑
    ● 1960 年に John McCarthy によってはじめて論文が発表された
    ○ 最初の仕組みはマークアンドスイープ ( Mark & Sweep )
    ○ LISP に実装された
    ● メモリ使用に注力し、確保と解放を自動化できる
    ● 今日では主要な言語ほぼすべてに採用されている
    ○ 多くの言語で GC 動作中の動作停止 ( STW: Stop the World ) が発生する

    View Slide

  63. #ooc_2020 #ooc_b 63
    Garbage Collection
    Overview
    タイミングとメモリリーク
    ● GC はメモリ使用量などが一定の閾値を超えた場合に実行される
    ○ マイナーGC
    ○ メジャーGC(フルGC)
    ● 複雑なプログラム構造からメモリの解放漏れ(メモリリーク)が発生する
    ○ 循環参照
    ○ クロージャ
    ○ 意図しないグローバル変数
    ○ タイマーやコールバックなどの増殖
    など

    View Slide

  64. #ooc_2020 #ooc_b 64
    Garbage Collection
    Overview
    代表的なアルゴリズム
    方式 説明
    参照カウント オブジェクトの参照数がゼロのものを削除する
    マークアンドスイープ 未使用のオブジェクトをマークした後に削除する
    マークアンドコンパクト 未使用のオブジェクトをマークした後に削除して詰める
    コピー 使用中のオブジェクトを別空間に移動して切り替える

    View Slide

  65. #ooc_2020 #ooc_b 65
    GC in PHP
    Garbage Collection inside Languages
    a: (refcount=1, is_ref=0)=class stdClass { }
    a: (refcount=2, is_ref=0)=class stdClass { }
    a: (refcount=1, is_ref=0)=class stdClass { }
    a: no such symbol

    View Slide

  66. #ooc_2020 #ooc_b 66
    GC in PHP
    Garbage Collection inside Languages
    a: (refcount=1, is_ref=0)=class stdClass { }
    b: (refcount=1, is_ref=0)=class stdClass { }
    a: (refcount=2, is_ref=0)=class stdClass { ... }
    b: (refcount=2, is_ref=0)=class stdClass { ... }
    a: (refcount=2, is_ref=0)=class stdClass { …. }
    b: no such symbol
    a: no such symbol
    b: no such symbol

    View Slide

  67. #ooc_2020 #ooc_b 67
    GC in PHP
    Garbage Collection inside Languages
    80
    864
    864
    32

    View Slide

  68. #ooc_2020 #ooc_b 68
    GC in PHP
    Garbage Collection inside Languages
    80
    864
    864
    32
    オブジェクトが循環参照している

    View Slide

  69. #ooc_2020 #ooc_b 69
    GC in PHP
    Garbage Collection inside Languages
    80
    864
    864
    32
    参照カウントがなくなっても回収されない

    View Slide

  70. #ooc_2020 #ooc_b 70
    GC in PHP
    Garbage Collection inside Languages
    80
    864
    864
    32
    強制GCによって回収された

    View Slide

  71. #ooc_2020 #ooc_b 71
    GC in PHP
    Garbage Collection inside Languages
    GC in PHP
    ● 参照カウント方式で GC が動作する
    ○ 循環参照オブジェクトも正しく回収される
    ○ PHP 5.2 以前は循環参照が回収されないので注意(誰も使ってないはず)
    ● 表面上は unset() 等で即座にアクセスできなくなる
    ● オブジェクトが閾値 ( 10,000 件 ) に達するまで回収されない
    ● PHP 7.4 より弱参照 ( WeakReference ) が実装された
    ○ GC による回収を阻害しないオブジェクト
    ○ メモリリークを防いだりキャッシュなどに利用

    View Slide

  72. #ooc_2020 #ooc_b 72
    GC in PHP
    Garbage Collection inside Languages
    80
    1280
    354
    354
    即座に解放

    View Slide

  73. #ooc_2020 #ooc_b 73
    三色マーキング
    Tricolor Marking
    灰色オブジェクト
    白色オブジェクト
    ● コレクターが到達し、全フィールド走査していないオブジェクト
    ● 生存可否が未確定の状態
    ● 全走査完了後に灰色は残らない
    ● コレクターが未到達のオブジェクト
    ● 処理終了後に白色の場合は回収される
    黒色オブジェクト ● コレクターが全フィールドに到達済みのオブジェクト
    ● 生存が確定し、これ以上走査の必要はない

    View Slide

  74. #ooc_2020 #ooc_b 74
    三色マーキング
    Tricolor Marking
    三色マーキングの手順
    1. すべてのオブジェクトが白色状態
    2. ルートオブジェクトをすべて走査し、到達したものを灰色に設定する
    3. ルートオブジェクトの内部オブジェクトを繰り返し走査する
    4. 内部探索が終わったオブジェクトを黒色に設定する
    5. すべての探索が終了後、灰色は残らず黒/白いずれかになる

    View Slide

  75. #ooc_2020 #ooc_b 75
    三色不変条件
    Tricolor Invariants
    弱い三色不変条件 ( the weak tricolor invariants )
    黒いオブジェクトから参照するすべてのオブジェクトが灰色保護されている
    強い三色不変条件 ( the strong tricolor invariants )
    黒いオブジェクトから参照する白いオブジェクトが存在しない
    $a
    $b
    $a
    $b
    ( 参考:https:/
    /www.slideshare.net/y-uti/php-gc )

    View Slide

  76. #ooc_2020 #ooc_b 76
    GC in Java
    Garbage Collection inside Languages
    $ java Demonstration
    Foundation Constructor
    Demonstration Constructor
    Demonstration Destructor
    Foundation Destructor
    ※ System.gc() および finalize() メソッドは非推奨

    View Slide

  77. #ooc_2020 #ooc_b 77
    GC in Java
    Garbage Collection inside Languages
    $ java Demonstration
    Foundation Constructor
    Demonstration Constructor

    View Slide

  78. #ooc_2020 #ooc_b 78
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Eden
    Survivor
    New ( Nursery )
    Old ( Tenured ) Permenent
    Java メモリ管理
    Java には多くの GC 機構が取り入れられている
    ● 世代別 GC
    ● コピー GC / コンパクション
    ● マークスイープ GC

    View Slide

  79. #ooc_2020 #ooc_b 79
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Eden
    Survivor
    New ( Nursery )
    Old ( Tenured ) Permenent
    GC の仕組み
    新しいオブジェクトをEden領域に割り当て

    View Slide

  80. #ooc_2020 #ooc_b 80
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Eden
    Survivor
    New ( Nursery )
    Old ( Tenured ) Permenent
    GC の仕組み
    Minor Garbage Collection
    (1) 不要データを削除
    (2) 必要データを Eden → To に移動

    View Slide

  81. #ooc_2020 #ooc_b 81
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Eden
    Survivor
    New ( Nursery )
    Old ( Tenured ) Permenent
    GC の仕組み
    Minor Garbage Collection
    (1) To → From を入れ替える

    View Slide

  82. #ooc_2020 #ooc_b 82
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Eden
    Survivor
    New ( Nursery )
    Old ( Tenured ) Permenent
    GC の仕組み
    Minor Garbage Collection
    (1) To → From を入れ替える
    (2) 不要データを削除
    (3) 必要データを Eden / From → To に移動

    View Slide

  83. #ooc_2020 #ooc_b 83
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Eden
    Survivor
    New ( Nursery )
    Old ( Tenured ) Permenent
    GC の仕組み
    Minor Garbage Collection
    (1) To → From を入れ替える
    (2) 不要データを削除
    (3) 必要データを Eden / From → To に移動
    (4) 年齢が一定に達したものを Old に移動

    View Slide

  84. #ooc_2020 #ooc_b 84
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Survivor
    New ( Nursery )
    Permenent
    GC の仕組み
    Full Garbage Collection
    ● Old へのメモリ割り当てが失敗した場合
    ● Young / Old 両方を対象とした回収処理
    ● Old からの退避領域はないため特殊な GC
    Eden
    Old ( Tenured )

    View Slide

  85. #ooc_2020 #ooc_b
    Eden 領域が不足している場合
    直接 Old 領域にオブジェクトが格納される
    85
    GC in Java
    Garbage Collection inside Languages
    VM
    Heap
    VM
    Stack
    From To
    Eden
    Survivor
    New ( Nursery )
    Old ( Tenured ) Permenent
    GC の仕組み

    View Slide

  86. #ooc_2020 #ooc_b 86
    GC in Java
    Garbage Collection inside Languages
    Out Of Memory Exception
    ● オブジェクト格納先メモリを確保できない
    ● GC が頻繁に発生しすぎた
    ● GC による回収領域が小さすぎた
    ● Permanent 領域が枯渇した
    など

    View Slide

  87. #ooc_2020 #ooc_b 87
    GC in Java
    Garbage Collection inside Languages
    Initial Mark
    Concurrent
    Mark & Preclean
    Remark
    Concurrent
    Sweep & Reset
    StW StW
    GC Thread
    Application Thread
    Concurrent Mark and Sweep
    ( Write Barrier )

    View Slide

  88. #ooc_2020 #ooc_b 88
    GC in Java
    Garbage Collection inside Languages
    Appendix - Java GC に関する有益な資料
    ● https:/
    /gihyo.jp/dev/serial/01/jvm-arc/0004
    ● https:/
    /blog.cybozu.io/entry/2018/05/29/080000
    ● https:/
    /wiki.openjdk.java.net/display/shenandoah/Main
    ● https:/
    /www.infoq.com/jp/news/2019/05/java12-released/
    ● https:/
    /www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-MA16-GC.pdf
    ● http:/
    /www.nminoru.jp/~nminoru/java/cms/concurrent_mark_sweep.html

    View Slide

  89. #ooc_2020 #ooc_b 89
    Regression
    原点回帰

    View Slide

  90. #ooc_2020 #ooc_b 90
    print “Hello, World”;

    View Slide

  91. #ooc_2020 #ooc_b 91
    ORG 0x7c00
    JMP SHORT entry
    DB 0x90
    DB "STARTIPL"
    DW 512
    DB 1
    DW 1
    DB 2
    DW 224
    DW 2880
    DB 0xf0
    DW 9
    DW 18
    DW 2
    DD 0
    DD 2880
    DB 0,0,0x29
    DD 0xffffffff
    DB "TESTIPLDISK"
    DB "FAT12 "
    TIMES 18 DB 0
    entry:
    MOV ax, 0
    MOV ss, ax
    MOV sp, 0x7c00
    MOV ds, ax
    MOV es, ax
    MOV si, msg
    putloop:
    MOV al, [si]
    ADD si, 1
    CMP al, 0
    JE fin
    MOV ah, 0x0e
    MOV bx, 15
    INT 0x10
    JMP putloop
    fin:
    HLT
    JMP fin
    msg:
    DB 0x0a, 0x0a
    DB "Hello, World"
    DB 0x0a
    DB 0
    TIMES 0x1fe-($-$$) DB 0
    DB 0x55, 0xaa
    DB 0xf0, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00
    TIMES 4600 DB 0
    DB 0xf0, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00
    TIMES 1469432 DB 0
    HELLO.IPL ( nasm )

    View Slide

  92. #ooc_2020 #ooc_b 92
    裏側まで深く知れば、強くなれる
    たまには別の「設計」にも目を向けよう

    View Slide

  93. #ooc_2020 #ooc_b 93
    Start thinking about new Object ();

    View Slide

  94. View Slide

  95. 95
    2020 / 6 / 27
    サークル募集中!

    View Slide

  96. 96
    Go To Next Session
    presented by

    View Slide

  97. Build Something Amazing
    This presentation written by @ariaki4dev

    View Slide

  98. #ABDCFF - #0396FF
    #CE9FFC - #7367F0
    #81FBB8 - #28C76F
    #FF96F9 - #C32BAC
    #4b4b4b
    98
    Learn about Object Lifecycle &
    Memory Management
    Object-Oriented Conference 2020
    #ooc_2020

    View Slide