SlideShare a Scribd company logo
1 of 156
Download to read offline
PHP の GC の話
2015/02/27
第87回PHP勉強会
なぜ GC の話を?
言語処理系の実装を知るのは良い勉強になる
GC はとても面白い
◦ 巧妙なアルゴリズム
◦ 高速化のための実装上の (低水準な) 工夫
両方まとめて楽しめる。しかも「本物の」コードで
2015/02/27 第87回 PHP 勉強会 2
なぜ GC の話を?
言語処理系の実装を知るのは良い勉強になる
GC はとても面白い
◦ 巧妙なアルゴリズム
◦ 高速化のための実装上の (低水準な) 工夫
両方まとめて楽しめる。しかも「本物の」コードで
今日はこちらの話を中心に・・・
2015/02/27 第87回 PHP 勉強会 3
自己紹介
内山 雄司
◦ 株式会社ピコラボ
◦ @y__uti
◦ http://y-uti.hatenablog.jp
好きな話題
◦ 機械学習とその周辺分野(ほぼ仕事)
◦ 楽しいけれど数学は不真面目だったので色々つらい
◦ プログラミング言語処理系(学生のときの研究分野/今は趣味)
◦ 去年あたり?から HHVM とか PHP7 とか盛り上がっていて楽しい
◦ PHP dis
2015/02/27 第87回 PHP 勉強会 4
目次
GC って何?
GC の仕組み
循環参照を持つゴミの回収
gc_disable() の話
2015/02/27 第87回 PHP 勉強会 5
GC って何?
2015/02/27 第87回 PHP 勉強会 6
Wikipedia によると・・・
ガベージコレクション (garbage collection; GC) とは、
プログラムが動的に確保したメモリ領域のうち、不要になった領
域を自動的に解放する機能
である。
2015/02/27 第87回 PHP 勉強会 7
http://ja.wikipedia.org/wiki/ガベージコレクション
memory_limit
PHP のスクリプトが使えるメモリの上限
2015/02/27 第87回 PHP 勉強会 8
$ cat php.ini
...
; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
memory_limit = 128M
...
メモリ不足のプログラム
128M を使いきってしまうと?
2015/02/27 第87回 PHP 勉強会 9
<?php
$a1 = range(1, 200000); echo '1';
$a2 = range(1, 200000); echo '2';
$a3 = range(1, 200000); echo '3';
$a4 = range(1, 200000); echo '4';
$a5 = range(1, 200000); echo '5';
見慣れた?エラー
1234PHP Fatal error: Allowed memory size of 134217728
bytes exhausted (tried to allocate 32 bytes) in ... on
line 6
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 10
memory_limit = 128M
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 11
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 12
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 13
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 14
$a1
$a2
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 15
$a1
$a2
$a3
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 16
$a1
$a2
$a3
$a4
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 17
$a1
$a2
$a3
$a4
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
プログラム実行の様子
2015/02/27 第87回 PHP 勉強会 18
$a1
$a2
$a3
$a4
PHP Fatal Error
変更版のプログラム
同じ変数 $a1 に代入する
2015/02/27 第87回 PHP 勉強会 19
<?php
$a1 = range(1, 200000); echo '1';
$a1 = range(1, 200000); echo '2';
$a1 = range(1, 200000); echo '3';
$a1 = range(1, 200000); echo '4';
$a1 = range(1, 200000); echo '5';
これはメモリ不足にならず実行できる
12345
どうして実行できるの?
◦ PHP には「ごみ集め」 (Garbage Collection) の仕組みがあるから
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 20
memory_limit = 128M
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 21
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 22
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 23
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 24
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 25
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 26
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 27
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP に GC がなかったら
2015/02/27 第87回 PHP 勉強会 28
$a1
PHP Fatal Error
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 29
memory_limit = 128M
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 30
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 31
$a1
←もう使わない
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 32
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 33
$a1
←もう使わない
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 34
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 35
$a1
←もう使わない
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 36
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 37
$a1
←もう使わない
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 38
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 39
$a1
←もう使わない
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 40
$a1
array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 41
$a1
←もう使わない
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 42
$a1
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 43
$a1
Happy!
GC の仕組み
2015/02/27 第87回 PHP 勉強会 44
GC の基本
「もう使わない」ことをどのように知るのか?
2015/02/27 第87回 PHP 勉強会 45
<?php
$a1 = range(1, 200000);
array(1, 2, ..., 200000)
$a1
問題:10000 を表示するには?
echo $a1[9999]; // 10000
GC の基本
「もう使わない」ことをどのように知るのか?
2015/02/27 第87回 PHP 勉強会 46
<?php
$a1 = range(1, 200000);
$a1 = range(200001, 400000);
array(200001, ..., 400000)
array(1, 2, ..., 200000)
$a1
問題:10000 を表示するには?
echo $a1[9999]; // 210000
◦ 無理
GC の基本
「もう使わない」ことをどのように知るのか?
◦ とても難しい
「もう使えない」ことを知る
◦ わりと簡単
◦ 辿れないものは使えない
2015/02/27 第87回 PHP 勉強会 47
array(200001, ..., 400000)
array(1, 2, ..., 200000)
$a1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 48
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 49
$a1 = new MyList();
1$a1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 50
$a1->next = new MyList();
1$a1 1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 51
$a1->next->next = new MyList();
1$a1 1 1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 52
$a2 = new MyList();
1$a1 1
$a2
1
1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 53
$a2->next = $a1->next;
1$a1 2
$a2
1
1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 54
$a1->next->next->next = new MyList();
1$a1 2
$a2
1
11
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 55
$a1->next->next->next->next = $a1->next->next->next;
1$a1 2
$a2
2
11
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 56
$a2 = new MyList();
1$a1 2
$a2
2
10
1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 57
$a1 = new MyList();
1$a1 1
$a2
2
1
1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 58
unset($a1);
0 1
$a2
2
1
1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 59
unset($a1);
0
$a2
2
1
1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 60
unset($a1);
$a2
1
1
1
PHP の GC
参照カウント方式
◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく
◦ 矢印の数が 0 になったら「もう使えない」
2015/02/27 第87回 PHP 勉強会 61
unset($a1);
$a2
1
1
1
これは?→
循環参照を持つごみの回収
2015/02/27 第87回 PHP 勉強会 62
循環参照
参照カウント方式の弱点
◦ 参照関係に循環があると矢印の数が 0 にならないまま辿れなくなる
◦ だんだん溜まっていき最後にはメモリ不足になってしまう
PHP 5.2 まで
◦ 辿れなくなる前に自分で unset しなければいけなかった
◦ つらい・・・普通バグる
2015/02/27 第87回 PHP 勉強会 63
$a2
1
1
1
循環参照の GC
PHP 5.3 以降
◦ 循環参照の問題にも対応
文献
◦ Concurrent Cycle Collection in Reference Counted Systems
◦ http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf
◦ http://www.ibm.com/ にアクセスして論文名でサイト内検索すれば見つかる
2015/02/27 第87回 PHP 勉強会 64
http://php.net/manual/ja/features.gc.collecting-cycles.php
循環参照の GC
PHP 5.3 以降
◦ 循環参照の問題にも対応
たとえば以下の状態から・・・
2015/02/27 第87回 PHP 勉強会 65
1$a1
$a2
2
2
1
1
1
2
2
2
循環参照の GC - Release
参照カウントが 0 になった場合
◦ ゴミなので回収する(通常の参照カウント方式)
2015/02/27 第87回 PHP 勉強会 66
unset($a1);
0
$a2
2
2
1
1
1
2
2
2
循環参照の GC - PossibleRoot
参照カウントが減ったがまだ 0 ではない場合
◦ ゴミができてしまった「かもしれない」
◦ 候補として覚えておく
2015/02/27 第87回 PHP 勉強会 67
$a2
1
2
1
1
1
2
2
2
やばい奴ら
循環参照の GC
必要に応じて候補をチェックする
◦ メモリ不足になった
◦ gc_collect_cycles() が呼ばれた
◦ 覚えきれなくなった (上限 10,000)
2015/02/27 第87回 PHP 勉強会 68
$a2
1
2
1
1
1
2
2
2
やばい奴ら
循環参照の GC
はじめに
◦ この図の全体を見渡すと・・・
2015/02/27 第87回 PHP 勉強会 69
$a2
1
2
1
1
1
2
2
2
やばい奴ら
ここはゴミ→
循環参照の GC - MarkRoots
候補のオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 70
$a2
1
2
1
1
1
2
2
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 71
$a2
1
2
1
0
1
2
2
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 72
$a2
1
2
1
0
1
1
2
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 73
$a2
1
2
1
0
1
1
1
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 74
$a2
1
2
1
0
1
0
1
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 75
$a2
1
2
1
0
1
0
1
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 76
$a2
1
2
1
0
1
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 77
$a2
1
2
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 78
$a2
1
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 79
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 80
$a2
0
0
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
今の状態
◦ 候補から到達できるオブジェクトは灰色
◦ 灰色以外からの参照のみカウント
2015/02/27 第87回 PHP 勉強会 81
$a2
0
0
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 82
$a2
0
0
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 83
$a2
0
0
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 84
$a2
0
0
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 85
$a2
0
0
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
2015/02/27 第87回 PHP 勉強会 86
$a2
0
0
1
0
0
0
0
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 87
$a2
0
0
1
0
0
0
1
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 88
$a2
0
0
1
0
0
1
1
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 89
$a2
0
0
1
0
0
1
2
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 90
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 91
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 92
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 93
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 94
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 95
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
今の状態
◦ 到達できるオブジェクトは黒
◦ 到達できないオブジェクトは白
2015/02/27 第87回 PHP 勉強会 96
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 97
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 98
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 99
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 100
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 101
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 102
$a2
0
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 103
$a2
0
1
0
0
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 104
$a2
0
1
0 1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 105
$a2
0
1
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 106
$a2
0
1
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
矢印を辿りながら
◦ 「白」のオブジェクトを回収する
2015/02/27 第87回 PHP 勉強会 107
$a2 1
1
2
2
やばい奴ら
循環参照の GC - CollectWhite
今の状態
◦ 到達できるオブジェクトのみ残っている
2015/02/27 第87回 PHP 勉強会 108
$a2 1
1
2
2
やばい奴ら
gc_disable() の話
2015/02/27 第87回 PHP 勉強会 109
循環参照の GC (再考)
最初の状態が以下だったとしたら・・・
2015/02/27 第87回 PHP 勉強会 110
1$a1
$a2
2
3
1
1
1
2
2
2
循環参照の GC - Release
参照カウントが 0 になった場合
◦ ゴミなので回収する(通常の参照カウント方式)
2015/02/27 第87回 PHP 勉強会 111
unset($a1);
0
$a2
2
3
1
1
1
2
2
2
循環参照の GC - PossibleRoot
参照カウントが減ったがまだ 0 ではない場合
◦ ゴミができてしまった「かもしれない」
◦ 候補として覚えておく
2015/02/27 第87回 PHP 勉強会 112
$a2
1
3
1
1
1
2
2
2
やばい奴ら
循環参照の GC - MarkRoots
候補のオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 113
$a2
1
3
1
1
1
2
2
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 114
$a2
1
3
1
0
1
2
2
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 115
$a2
1
3
1
0
1
1
2
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 116
$a2
1
3
1
0
1
1
1
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 117
$a2
1
3
1
0
1
0
1
2
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 118
$a2
1
3
1
0
1
0
1
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 119
$a2
1
3
1
0
1
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 120
$a2
1
3
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 121
$a2
1
2
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 122
$a2
0
2
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
矢印を辿りながら
◦ 参照カウントを 1 減らす
◦ 辿ったオブジェクトを「灰色」にする
2015/02/27 第87回 PHP 勉強会 123
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - MarkGray
今の状態
◦ 候補から到達できるオブジェクトは灰色
◦ 灰色以外からの参照のみカウント
2015/02/27 第87回 PHP 勉強会 124
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 125
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 126
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 127
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
2015/02/27 第87回 PHP 勉強会 128
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
2015/02/27 第87回 PHP 勉強会 129
$a2
0
1
1
0
0
0
0
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 130
$a2
0
1
1
0
0
0
1
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 131
$a2
0
1
1
0
0
1
1
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 132
$a2
0
1
1
0
0
1
2
1
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 133
$a2
0
1
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 134
$a2
0
1
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 135
$a2
0
1
1
0
0
1
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 136
$a2
0
1
1
0
0
1
2
2
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 137
$a2
1
1
1
0
0
1
2
2
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 138
$a2
1
1
1
1
0
1
2
2
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 139
$a2
1
1
1
1
0
2
2
2
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 140
$a2
1
1
1
1
1
2
2
2
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 141
$a2
1
2
1
1
1
2
2
2
やばい奴ら
循環参照の GC - ScanBlack
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 142
$a2
1
3
1
1
1
2
2
2
やばい奴ら
循環参照の GC - Scan
矢印を辿りながら
◦ 参照カウントが 0 なら「白」にする
◦ 1 以上なら「黒」にして・・・
◦ 減らしてしまった参照カウントを戻していく
2015/02/27 第87回 PHP 勉強会 143
$a2
1
3
1
1
1
2
2
2
やばい奴ら
循環参照の GC
ゴミなど一つも無かった
◦ 時間の無駄
2015/02/27 第87回 PHP 勉強会 144
$a2
1
3
1
1
1
2
2
2
やばい奴ら
ところで
2015/02/27 第87回 PHP 勉強会 145
ゴミの候補はいつできる?
関数を呼ぶだけでゴミの候補が増える (引数の型による)
2015/02/27 第87回 PHP 勉強会 146
<?php
$a = new MyList();
function doSomething($foo) {}
doSomething($a);
ゴミの候補はいつできる?
関数を呼ぶだけでゴミの候補が増える (引数の型による)
2015/02/27 第87回 PHP 勉強会 147
<?php
$a = new MyList();
function doSomething($foo) {}
doSomething($a);
$a 1
◦ doSomething 実行前
ゴミの候補はいつできる?
関数を呼ぶだけでゴミの候補が増える (引数の型による)
2015/02/27 第87回 PHP 勉強会 148
<?php
$a = new MyList();
function doSomething($foo) {}
doSomething($a);
$a 2
$foo
◦ doSomething 実行中
ゴミの候補はいつできる?
関数を呼ぶだけでゴミの候補が増える (引数の型による)
2015/02/27 第87回 PHP 勉強会 149
<?php
$a = new MyList();
function doSomething($foo) {}
doSomething($a);
$a 1
◦ doSomething 実行後
gc_disable() の使いどころ
原則
◦ 普通は gc_disable() なんて考えなくてよい
◦ メモリリークの元
次のようなプログラムは検討の余地あり
◦ 巨大なグラフ (or 木, リスト, ...) を辿りながら処理する
◦ そのグラフは循環参照によるゴミを出さない
2015/02/27 第87回 PHP 勉強会 150
実験
こんなデータ構造を作って各要素を引数に関数を呼ぶ
2015/02/27 第87回 PHP 勉強会 151
1
・・・
1
1
・・・
1
1
1
・・・
・・・
配列
リスト
実験
こんなデータ構造を作って各要素を引数に関数を呼ぶ
2015/02/27 第87回 PHP 勉強会 152
1
・・・
1
1
・・・
1
1
1
・・・
・・・
配列
リスト
配列の要素数によって循環参照の GC が
発生したり発生しなかったりする
実験
プログラム (データ構造を組み立てる部分は省略)
2015/02/27 第87回 PHP 勉強会 153
...
gc_collect_cycles();
$start = microtime(true);
for ($i = 0; $i < 10; ++$i) {
foreach ($arrayOfList as $list) {
doSomething($list); // doSomething は空の関数
}
}
$end = microtime(true);
◦ $arrayOfList の要素数を変更しながら ($end - $start) を計測
◦ $list の長さは固定 (100 とした)
実験結果
2015/02/27 第87回 PHP 勉強会 154
PHP 5.6.5 との比較
memory_limit=1024M として実験
Core i5-3337U 1.80GHz
実験結果
2015/02/27 第87回 PHP 勉強会 155
PHP 7.0.0 との比較
memory_limit=1024M として実験
Core i5-3337U 1.80GHz
おわり
ありがとうございました
2015/02/27 第87回 PHP 勉強会 156

More Related Content

What's hot

Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターンSoudai Sone
 
フロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjugフロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjugItsuki Kuroda
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 Hiroshi Ito
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!Genya Murakami
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門泰 増田
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpsonickun
 
C/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールC/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールMITSUNARI Shigeo
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するYoshifumi Kawai
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐりKazuyuki TAKASE
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数Shinichi Kozake
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側do_aki
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるAtsushi KOMIYA
 
型安全性入門
型安全性入門型安全性入門
型安全性入門Akinori Abe
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチンyohhoy
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク7shi
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門masayoshi takahashi
 

What's hot (20)

Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
フロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjugフロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjug
 
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3 データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
 
すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!すごい constexpr たのしくレイトレ!
すごい constexpr たのしくレイトレ!
 
Oss貢献超入門
Oss貢献超入門Oss貢献超入門
Oss貢献超入門
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
 
RSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjpRSA暗号運用でやってはいけない n のこと #ssmjp
RSA暗号運用でやってはいけない n のこと #ssmjp
 
C/C++プログラマのための開発ツール
C/C++プログラマのための開発ツールC/C++プログラマのための開発ツール
C/C++プログラマのための開発ツール
 
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭するCEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
CEDEC 2018 最速のC#の書き方 - C#大統一理論へ向けて性能的課題を払拭する
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
PHPとシグナル、その裏側
PHPとシグナル、その裏側PHPとシグナル、その裏側
PHPとシグナル、その裏側
 
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみるDSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
 
型安全性入門
型安全性入門型安全性入門
型安全性入門
 
20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン20分くらいでわかった気分になれるC++20コルーチン
20分くらいでわかった気分になれるC++20コルーチン
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク
 
何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門何となく勉強した気分になれるパーサ入門
何となく勉強した気分になれるパーサ入門
 

Viewers also liked

みんなそろそろ707やめようぜ (;´Д`)
みんなそろそろ707やめようぜ (;´Д`)みんなそろそろ707やめようぜ (;´Д`)
みんなそろそろ707やめようぜ (;´Д`)Yasutaka Hamada
 
『例えば、PHPを避ける』以降PHPはどれだけ安全になったか
『例えば、PHPを避ける』以降PHPはどれだけ安全になったか『例えば、PHPを避ける』以降PHPはどれだけ安全になったか
『例えば、PHPを避ける』以降PHPはどれだけ安全になったかHiroshi Tokumaru
 
知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数Wataru Terada
 
営業・運用を支える "気付ける" 管理画面
営業・運用を支える "気付ける" 管理画面営業・運用を支える "気付ける" 管理画面
営業・運用を支える "気付ける" 管理画面Masao Maeda
 
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い sasezaki
 
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。sasezaki
 
脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015ichikaway
 
いまどきのPHP開発現場 -2015年秋-
いまどきのPHP開発現場 -2015年秋-いまどきのPHP開発現場 -2015年秋-
いまどきのPHP開発現場 -2015年秋-Masashi Shinbara
 
PHPの今とこれから2015
PHPの今とこれから2015PHPの今とこれから2015
PHPの今とこれから2015Rui Hirokawa
 

Viewers also liked (9)

みんなそろそろ707やめようぜ (;´Д`)
みんなそろそろ707やめようぜ (;´Д`)みんなそろそろ707やめようぜ (;´Д`)
みんなそろそろ707やめようぜ (;´Д`)
 
『例えば、PHPを避ける』以降PHPはどれだけ安全になったか
『例えば、PHPを避ける』以降PHPはどれだけ安全になったか『例えば、PHPを避ける』以降PHPはどれだけ安全になったか
『例えば、PHPを避ける』以降PHPはどれだけ安全になったか
 
知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数
 
営業・運用を支える "気付ける" 管理画面
営業・運用を支える "気付ける" 管理画面営業・運用を支える "気付ける" 管理画面
営業・運用を支える "気付ける" 管理画面
 
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
なぜ、PHPのmbstring.func_overloadをdeprecatedにするのに5年かかったのか? - 慢心、環境の違い
 
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
PHP、おまえだったのか。 いつもHTTPメッセージを 運んでくれたのは。
 
脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015脆弱性もバグ、だからテストしよう PHPカンファンレス2015
脆弱性もバグ、だからテストしよう PHPカンファンレス2015
 
いまどきのPHP開発現場 -2015年秋-
いまどきのPHP開発現場 -2015年秋-いまどきのPHP開発現場 -2015年秋-
いまどきのPHP開発現場 -2015年秋-
 
PHPの今とこれから2015
PHPの今とこれから2015PHPの今とこれから2015
PHPの今とこれから2015
 

Similar to PHP の GC の話

先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPress先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPressMasashi Shinbara
 
PHPの今とこれから2008
PHPの今とこれから2008PHPの今とこれから2008
PHPの今とこれから2008Rui Hirokawa
 
10分で分かる最近のCakePHP
10分で分かる最近のCakePHP10分で分かる最近のCakePHP
10分で分かる最近のCakePHPMasashi Shinbara
 
8分で分かる最近のCakePHP
8分で分かる最近のCakePHP8分で分かる最近のCakePHP
8分で分かる最近のCakePHPMasashi Shinbara
 
PHPの関数実行とその計測
PHPの関数実行とその計測PHPの関数実行とその計測
PHPの関数実行とその計測shinjiigarashi
 
PHPの今とこれから2021
PHPの今とこれから2021PHPの今とこれから2021
PHPの今とこれから2021Rui Hirokawa
 
PECL operator で演算子オーバーロード
PECL operator で演算子オーバーロードPECL operator で演算子オーバーロード
PECL operator で演算子オーバーロードy-uti
 
A Road map of Data Analysis for Visualization with D3.js
A Road map of Data Analysis for Visualization with D3.jsA Road map of Data Analysis for Visualization with D3.js
A Road map of Data Analysis for Visualization with D3.js博三 太田
 
CPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したいCPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したいcharsbar
 
FukuokaPHP 3
FukuokaPHP 3FukuokaPHP 3
FukuokaPHP 3ichikaway
 
Phpmatsuri2011 LT j_nakada
Phpmatsuri2011 LT j_nakadaPhpmatsuri2011 LT j_nakada
Phpmatsuri2011 LT j_nakadaJunpei Nakada
 
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ーWeb デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ーKite Koga
 
ng-mtg#6 AngularJS ディレクティブ・パターン
ng-mtg#6 AngularJS ディレクティブ・パターンng-mtg#6 AngularJS ディレクティブ・パターン
ng-mtg#6 AngularJS ディレクティブ・パターンHayashi Yuichi
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)Hiroaki KOBAYASHI
 
PHPの今とこれから2022
PHPの今とこれから2022PHPの今とこれから2022
PHPの今とこれから2022Rui Hirokawa
 
ゼロから始めるSparkSQL徹底活用!
ゼロから始めるSparkSQL徹底活用!ゼロから始めるSparkSQL徹底活用!
ゼロから始めるSparkSQL徹底活用!Nagato Kasaki
 
最近の PHP の話
最近の PHP の話最近の PHP の話
最近の PHP の話y-uti
 
PHPの今とこれから2019
PHPの今とこれから2019PHPの今とこれから2019
PHPの今とこれから2019Rui Hirokawa
 
Windows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみたWindows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみたy-uti
 

Similar to PHP の GC の話 (20)

先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPress先取り!PHP 7 と WordPress
先取り!PHP 7 と WordPress
 
PHPの今とこれから2008
PHPの今とこれから2008PHPの今とこれから2008
PHPの今とこれから2008
 
10分で分かる最近のCakePHP
10分で分かる最近のCakePHP10分で分かる最近のCakePHP
10分で分かる最近のCakePHP
 
8分で分かる最近のCakePHP
8分で分かる最近のCakePHP8分で分かる最近のCakePHP
8分で分かる最近のCakePHP
 
PHPの関数実行とその計測
PHPの関数実行とその計測PHPの関数実行とその計測
PHPの関数実行とその計測
 
PHPの今とこれから2021
PHPの今とこれから2021PHPの今とこれから2021
PHPの今とこれから2021
 
PECL operator で演算子オーバーロード
PECL operator で演算子オーバーロードPECL operator で演算子オーバーロード
PECL operator で演算子オーバーロード
 
A Road map of Data Analysis for Visualization with D3.js
A Road map of Data Analysis for Visualization with D3.jsA Road map of Data Analysis for Visualization with D3.js
A Road map of Data Analysis for Visualization with D3.js
 
CPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したいCPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したい
 
FukuokaPHP 3
FukuokaPHP 3FukuokaPHP 3
FukuokaPHP 3
 
Phpmatsuri2011 LT j_nakada
Phpmatsuri2011 LT j_nakadaPhpmatsuri2011 LT j_nakada
Phpmatsuri2011 LT j_nakada
 
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ーWeb デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
Web デザイナーが身に付けておきたい定番スキル ーPHP 初級編ー
 
ng-mtg#6 AngularJS ディレクティブ・パターン
ng-mtg#6 AngularJS ディレクティブ・パターンng-mtg#6 AngularJS ディレクティブ・パターン
ng-mtg#6 AngularJS ディレクティブ・パターン
 
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
仕事の手離れを良くする手段としての、静的検査のあるテンプレートエンジン (YATT::Lite talk at 2014 テンプレートエンジンNight)
 
PHPの今とこれから2022
PHPの今とこれから2022PHPの今とこれから2022
PHPの今とこれから2022
 
ゼロから始めるSparkSQL徹底活用!
ゼロから始めるSparkSQL徹底活用!ゼロから始めるSparkSQL徹底活用!
ゼロから始めるSparkSQL徹底活用!
 
最近の PHP の話
最近の PHP の話最近の PHP の話
最近の PHP の話
 
PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5
 
PHPの今とこれから2019
PHPの今とこれから2019PHPの今とこれから2019
PHPの今とこれから2019
 
Windows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみたWindows で拡張モジュールをビルドしてみた
Windows で拡張モジュールをビルドしてみた
 

More from y-uti

潜在ディリクレ配分法
潜在ディリクレ配分法潜在ディリクレ配分法
潜在ディリクレ配分法y-uti
 
Active Object
Active ObjectActive Object
Active Objecty-uti
 
目で見る過学習と正則化
目で見る過学習と正則化目で見る過学習と正則化
目で見る過学習と正則化y-uti
 
ロジスティック回帰入門
ロジスティック回帰入門ロジスティック回帰入門
ロジスティック回帰入門y-uti
 
論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...
論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...
論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...y-uti
 
PHP-ML で手書き数字認識
PHP-ML で手書き数字認識PHP-ML で手書き数字認識
PHP-ML で手書き数字認識y-uti
 
OPcache の最適化器の今
OPcache の最適化器の今OPcache の最適化器の今
OPcache の最適化器の今y-uti
 
スパース推定
スパース推定スパース推定
スパース推定y-uti
 
Kaggle の Titanic チュートリアルに挑戦した話
Kaggle の Titanic チュートリアルに挑戦した話Kaggle の Titanic チュートリアルに挑戦した話
Kaggle の Titanic チュートリアルに挑戦した話y-uti
 
PHP カンファレンス福岡 2017 参加報告
PHP カンファレンス福岡 2017 参加報告PHP カンファレンス福岡 2017 参加報告
PHP カンファレンス福岡 2017 参加報告y-uti
 
分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用y-uti
 
JIT のコードを読んでみた
JIT のコードを読んでみたJIT のコードを読んでみた
JIT のコードを読んでみたy-uti
 
JIT for PHP を試した
JIT for PHP を試したJIT for PHP を試した
JIT for PHP を試したy-uti
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試したy-uti
 
anyenv + phpenv + php-build が便利すぎる件
anyenv + phpenv + php-build が便利すぎる件anyenv + phpenv + php-build が便利すぎる件
anyenv + phpenv + php-build が便利すぎる件y-uti
 
PHP カンファレンス福岡 参加報告
PHP カンファレンス福岡 参加報告PHP カンファレンス福岡 参加報告
PHP カンファレンス福岡 参加報告y-uti
 
RFC: "var" Deprecation
RFC: "var" DeprecationRFC: "var" Deprecation
RFC: "var" Deprecationy-uti
 
PECL を数えてみた
PECL を数えてみたPECL を数えてみた
PECL を数えてみたy-uti
 
Windows で PHP をビルドしてみた
Windows で PHP をビルドしてみたWindows で PHP をビルドしてみた
Windows で PHP をビルドしてみたy-uti
 
逐次ベイズ学習 - サンプリング近似法の場合 -
逐次ベイズ学習 - サンプリング近似法の場合 -逐次ベイズ学習 - サンプリング近似法の場合 -
逐次ベイズ学習 - サンプリング近似法の場合 -y-uti
 

More from y-uti (20)

潜在ディリクレ配分法
潜在ディリクレ配分法潜在ディリクレ配分法
潜在ディリクレ配分法
 
Active Object
Active ObjectActive Object
Active Object
 
目で見る過学習と正則化
目で見る過学習と正則化目で見る過学習と正則化
目で見る過学習と正則化
 
ロジスティック回帰入門
ロジスティック回帰入門ロジスティック回帰入門
ロジスティック回帰入門
 
論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...
論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...
論文紹介 Identifying Implementation Bugs in Machine Learning based Image Classifi...
 
PHP-ML で手書き数字認識
PHP-ML で手書き数字認識PHP-ML で手書き数字認識
PHP-ML で手書き数字認識
 
OPcache の最適化器の今
OPcache の最適化器の今OPcache の最適化器の今
OPcache の最適化器の今
 
スパース推定
スパース推定スパース推定
スパース推定
 
Kaggle の Titanic チュートリアルに挑戦した話
Kaggle の Titanic チュートリアルに挑戦した話Kaggle の Titanic チュートリアルに挑戦した話
Kaggle の Titanic チュートリアルに挑戦した話
 
PHP カンファレンス福岡 2017 参加報告
PHP カンファレンス福岡 2017 参加報告PHP カンファレンス福岡 2017 参加報告
PHP カンファレンス福岡 2017 参加報告
 
分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用分類問題 - 機械学習ライブラリ scikit-learn の活用
分類問題 - 機械学習ライブラリ scikit-learn の活用
 
JIT のコードを読んでみた
JIT のコードを読んでみたJIT のコードを読んでみた
JIT のコードを読んでみた
 
JIT for PHP を試した
JIT for PHP を試したJIT for PHP を試した
JIT for PHP を試した
 
Task Spooler を試した
Task Spooler を試したTask Spooler を試した
Task Spooler を試した
 
anyenv + phpenv + php-build が便利すぎる件
anyenv + phpenv + php-build が便利すぎる件anyenv + phpenv + php-build が便利すぎる件
anyenv + phpenv + php-build が便利すぎる件
 
PHP カンファレンス福岡 参加報告
PHP カンファレンス福岡 参加報告PHP カンファレンス福岡 参加報告
PHP カンファレンス福岡 参加報告
 
RFC: "var" Deprecation
RFC: "var" DeprecationRFC: "var" Deprecation
RFC: "var" Deprecation
 
PECL を数えてみた
PECL を数えてみたPECL を数えてみた
PECL を数えてみた
 
Windows で PHP をビルドしてみた
Windows で PHP をビルドしてみたWindows で PHP をビルドしてみた
Windows で PHP をビルドしてみた
 
逐次ベイズ学習 - サンプリング近似法の場合 -
逐次ベイズ学習 - サンプリング近似法の場合 -逐次ベイズ学習 - サンプリング近似法の場合 -
逐次ベイズ学習 - サンプリング近似法の場合 -
 

PHP の GC の話

  • 1. PHP の GC の話 2015/02/27 第87回PHP勉強会
  • 2. なぜ GC の話を? 言語処理系の実装を知るのは良い勉強になる GC はとても面白い ◦ 巧妙なアルゴリズム ◦ 高速化のための実装上の (低水準な) 工夫 両方まとめて楽しめる。しかも「本物の」コードで 2015/02/27 第87回 PHP 勉強会 2
  • 3. なぜ GC の話を? 言語処理系の実装を知るのは良い勉強になる GC はとても面白い ◦ 巧妙なアルゴリズム ◦ 高速化のための実装上の (低水準な) 工夫 両方まとめて楽しめる。しかも「本物の」コードで 今日はこちらの話を中心に・・・ 2015/02/27 第87回 PHP 勉強会 3
  • 4. 自己紹介 内山 雄司 ◦ 株式会社ピコラボ ◦ @y__uti ◦ http://y-uti.hatenablog.jp 好きな話題 ◦ 機械学習とその周辺分野(ほぼ仕事) ◦ 楽しいけれど数学は不真面目だったので色々つらい ◦ プログラミング言語処理系(学生のときの研究分野/今は趣味) ◦ 去年あたり?から HHVM とか PHP7 とか盛り上がっていて楽しい ◦ PHP dis 2015/02/27 第87回 PHP 勉強会 4
  • 7. Wikipedia によると・・・ ガベージコレクション (garbage collection; GC) とは、 プログラムが動的に確保したメモリ領域のうち、不要になった領 域を自動的に解放する機能 である。 2015/02/27 第87回 PHP 勉強会 7 http://ja.wikipedia.org/wiki/ガベージコレクション
  • 8. memory_limit PHP のスクリプトが使えるメモリの上限 2015/02/27 第87回 PHP 勉強会 8 $ cat php.ini ... ; Maximum amount of memory a script may consume (128MB) ; http://php.net/memory-limit memory_limit = 128M ...
  • 9. メモリ不足のプログラム 128M を使いきってしまうと? 2015/02/27 第87回 PHP 勉強会 9 <?php $a1 = range(1, 200000); echo '1'; $a2 = range(1, 200000); echo '2'; $a3 = range(1, 200000); echo '3'; $a4 = range(1, 200000); echo '4'; $a5 = range(1, 200000); echo '5'; 見慣れた?エラー 1234PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in ... on line 6
  • 10. プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 10 memory_limit = 128M
  • 11. array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 11
  • 12. array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 12 $a1
  • 13. array(1, 2, ..., 200000) array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 13 $a1
  • 14. array(1, 2, ..., 200000) array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 14 $a1 $a2
  • 15. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 15 $a1 $a2 $a3
  • 16. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 16 $a1 $a2 $a3 $a4
  • 17. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 17 $a1 $a2 $a3 $a4
  • 18. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) プログラム実行の様子 2015/02/27 第87回 PHP 勉強会 18 $a1 $a2 $a3 $a4 PHP Fatal Error
  • 19. 変更版のプログラム 同じ変数 $a1 に代入する 2015/02/27 第87回 PHP 勉強会 19 <?php $a1 = range(1, 200000); echo '1'; $a1 = range(1, 200000); echo '2'; $a1 = range(1, 200000); echo '3'; $a1 = range(1, 200000); echo '4'; $a1 = range(1, 200000); echo '5'; これはメモリ不足にならず実行できる 12345 どうして実行できるの? ◦ PHP には「ごみ集め」 (Garbage Collection) の仕組みがあるから
  • 20. PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 20 memory_limit = 128M
  • 21. array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 21
  • 22. array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 22 $a1
  • 23. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 23 $a1
  • 24. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 24 $a1
  • 25. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 25 $a1
  • 26. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 26 $a1
  • 27. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 27 $a1
  • 28. array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP に GC がなかったら 2015/02/27 第87回 PHP 勉強会 28 $a1 PHP Fatal Error
  • 29. PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 29 memory_limit = 128M
  • 30. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 30 $a1
  • 31. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 31 $a1 ←もう使わない
  • 32. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 32 $a1
  • 33. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 33 $a1 ←もう使わない
  • 34. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 34 $a1
  • 35. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 35 $a1 ←もう使わない
  • 36. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 36 $a1
  • 37. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 37 $a1 ←もう使わない
  • 38. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 38 $a1
  • 39. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 39 $a1 ←もう使わない
  • 40. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 40 $a1
  • 41. array(1, 2, ..., 200000) array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 41 $a1 ←もう使わない
  • 42. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 42 $a1
  • 43. array(1, 2, ..., 200000) PHP には GC があるので 2015/02/27 第87回 PHP 勉強会 43 $a1 Happy!
  • 45. GC の基本 「もう使わない」ことをどのように知るのか? 2015/02/27 第87回 PHP 勉強会 45 <?php $a1 = range(1, 200000); array(1, 2, ..., 200000) $a1 問題:10000 を表示するには? echo $a1[9999]; // 10000
  • 46. GC の基本 「もう使わない」ことをどのように知るのか? 2015/02/27 第87回 PHP 勉強会 46 <?php $a1 = range(1, 200000); $a1 = range(200001, 400000); array(200001, ..., 400000) array(1, 2, ..., 200000) $a1 問題:10000 を表示するには? echo $a1[9999]; // 210000 ◦ 無理
  • 47. GC の基本 「もう使わない」ことをどのように知るのか? ◦ とても難しい 「もう使えない」ことを知る ◦ わりと簡単 ◦ 辿れないものは使えない 2015/02/27 第87回 PHP 勉強会 47 array(200001, ..., 400000) array(1, 2, ..., 200000) $a1
  • 48. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 48
  • 49. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 49 $a1 = new MyList(); 1$a1
  • 50. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 50 $a1->next = new MyList(); 1$a1 1
  • 51. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 51 $a1->next->next = new MyList(); 1$a1 1 1
  • 52. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 52 $a2 = new MyList(); 1$a1 1 $a2 1 1
  • 53. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 53 $a2->next = $a1->next; 1$a1 2 $a2 1 1
  • 54. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 54 $a1->next->next->next = new MyList(); 1$a1 2 $a2 1 11
  • 55. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 55 $a1->next->next->next->next = $a1->next->next->next; 1$a1 2 $a2 2 11
  • 56. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 56 $a2 = new MyList(); 1$a1 2 $a2 2 10 1
  • 57. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 57 $a1 = new MyList(); 1$a1 1 $a2 2 1 1
  • 58. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 58 unset($a1); 0 1 $a2 2 1 1
  • 59. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 59 unset($a1); 0 $a2 2 1 1
  • 60. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 60 unset($a1); $a2 1 1 1
  • 61. PHP の GC 参照カウント方式 ◦ 自分に入ってくる矢印 (= 参照) の数を記録しておく ◦ 矢印の数が 0 になったら「もう使えない」 2015/02/27 第87回 PHP 勉強会 61 unset($a1); $a2 1 1 1 これは?→
  • 63. 循環参照 参照カウント方式の弱点 ◦ 参照関係に循環があると矢印の数が 0 にならないまま辿れなくなる ◦ だんだん溜まっていき最後にはメモリ不足になってしまう PHP 5.2 まで ◦ 辿れなくなる前に自分で unset しなければいけなかった ◦ つらい・・・普通バグる 2015/02/27 第87回 PHP 勉強会 63 $a2 1 1 1
  • 64. 循環参照の GC PHP 5.3 以降 ◦ 循環参照の問題にも対応 文献 ◦ Concurrent Cycle Collection in Reference Counted Systems ◦ http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon01Concurrent.pdf ◦ http://www.ibm.com/ にアクセスして論文名でサイト内検索すれば見つかる 2015/02/27 第87回 PHP 勉強会 64 http://php.net/manual/ja/features.gc.collecting-cycles.php
  • 65. 循環参照の GC PHP 5.3 以降 ◦ 循環参照の問題にも対応 たとえば以下の状態から・・・ 2015/02/27 第87回 PHP 勉強会 65 1$a1 $a2 2 2 1 1 1 2 2 2
  • 66. 循環参照の GC - Release 参照カウントが 0 になった場合 ◦ ゴミなので回収する(通常の参照カウント方式) 2015/02/27 第87回 PHP 勉強会 66 unset($a1); 0 $a2 2 2 1 1 1 2 2 2
  • 67. 循環参照の GC - PossibleRoot 参照カウントが減ったがまだ 0 ではない場合 ◦ ゴミができてしまった「かもしれない」 ◦ 候補として覚えておく 2015/02/27 第87回 PHP 勉強会 67 $a2 1 2 1 1 1 2 2 2 やばい奴ら
  • 68. 循環参照の GC 必要に応じて候補をチェックする ◦ メモリ不足になった ◦ gc_collect_cycles() が呼ばれた ◦ 覚えきれなくなった (上限 10,000) 2015/02/27 第87回 PHP 勉強会 68 $a2 1 2 1 1 1 2 2 2 やばい奴ら
  • 69. 循環参照の GC はじめに ◦ この図の全体を見渡すと・・・ 2015/02/27 第87回 PHP 勉強会 69 $a2 1 2 1 1 1 2 2 2 やばい奴ら ここはゴミ→
  • 70. 循環参照の GC - MarkRoots 候補のオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 70 $a2 1 2 1 1 1 2 2 2 やばい奴ら
  • 71. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 71 $a2 1 2 1 0 1 2 2 2 やばい奴ら
  • 72. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 72 $a2 1 2 1 0 1 1 2 2 やばい奴ら
  • 73. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 73 $a2 1 2 1 0 1 1 1 2 やばい奴ら
  • 74. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 74 $a2 1 2 1 0 1 0 1 2 やばい奴ら
  • 75. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 75 $a2 1 2 1 0 1 0 1 1 やばい奴ら
  • 76. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 76 $a2 1 2 1 0 1 0 0 1 やばい奴ら
  • 77. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 77 $a2 1 2 1 0 0 0 0 1 やばい奴ら
  • 78. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 78 $a2 1 1 1 0 0 0 0 1 やばい奴ら
  • 79. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 79 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 80. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 80 $a2 0 0 1 0 0 0 0 1 やばい奴ら
  • 81. 循環参照の GC - MarkGray 今の状態 ◦ 候補から到達できるオブジェクトは灰色 ◦ 灰色以外からの参照のみカウント 2015/02/27 第87回 PHP 勉強会 81 $a2 0 0 1 0 0 0 0 1 やばい奴ら
  • 82. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 82 $a2 0 0 1 0 0 0 0 1 やばい奴ら
  • 83. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 83 $a2 0 0 1 0 0 0 0 1 やばい奴ら
  • 84. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 84 $a2 0 0 1 0 0 0 0 1 やばい奴ら
  • 85. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 85 $a2 0 0 1 0 0 0 0 1 やばい奴ら
  • 86. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ 2015/02/27 第87回 PHP 勉強会 86 $a2 0 0 1 0 0 0 0 1 やばい奴ら
  • 87. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 87 $a2 0 0 1 0 0 0 1 1 やばい奴ら
  • 88. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 88 $a2 0 0 1 0 0 1 1 1 やばい奴ら
  • 89. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 89 $a2 0 0 1 0 0 1 2 1 やばい奴ら
  • 90. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 90 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 91. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 91 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 92. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 92 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 93. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 93 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 94. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 94 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 95. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 95 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 96. 循環参照の GC - Scan 今の状態 ◦ 到達できるオブジェクトは黒 ◦ 到達できないオブジェクトは白 2015/02/27 第87回 PHP 勉強会 96 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 97. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 97 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 98. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 98 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 99. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 99 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 100. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 100 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 101. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 101 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 102. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 102 $a2 0 0 1 0 0 1 2 2 やばい奴ら
  • 103. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 103 $a2 0 1 0 0 1 2 2 やばい奴ら
  • 104. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 104 $a2 0 1 0 1 2 2 やばい奴ら
  • 105. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 105 $a2 0 1 1 2 2 やばい奴ら
  • 106. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 106 $a2 0 1 1 2 2 やばい奴ら
  • 107. 循環参照の GC - CollectWhite 矢印を辿りながら ◦ 「白」のオブジェクトを回収する 2015/02/27 第87回 PHP 勉強会 107 $a2 1 1 2 2 やばい奴ら
  • 108. 循環参照の GC - CollectWhite 今の状態 ◦ 到達できるオブジェクトのみ残っている 2015/02/27 第87回 PHP 勉強会 108 $a2 1 1 2 2 やばい奴ら
  • 111. 循環参照の GC - Release 参照カウントが 0 になった場合 ◦ ゴミなので回収する(通常の参照カウント方式) 2015/02/27 第87回 PHP 勉強会 111 unset($a1); 0 $a2 2 3 1 1 1 2 2 2
  • 112. 循環参照の GC - PossibleRoot 参照カウントが減ったがまだ 0 ではない場合 ◦ ゴミができてしまった「かもしれない」 ◦ 候補として覚えておく 2015/02/27 第87回 PHP 勉強会 112 $a2 1 3 1 1 1 2 2 2 やばい奴ら
  • 113. 循環参照の GC - MarkRoots 候補のオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 113 $a2 1 3 1 1 1 2 2 2 やばい奴ら
  • 114. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 114 $a2 1 3 1 0 1 2 2 2 やばい奴ら
  • 115. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 115 $a2 1 3 1 0 1 1 2 2 やばい奴ら
  • 116. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 116 $a2 1 3 1 0 1 1 1 2 やばい奴ら
  • 117. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 117 $a2 1 3 1 0 1 0 1 2 やばい奴ら
  • 118. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 118 $a2 1 3 1 0 1 0 1 1 やばい奴ら
  • 119. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 119 $a2 1 3 1 0 1 0 0 1 やばい奴ら
  • 120. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 120 $a2 1 3 1 0 0 0 0 1 やばい奴ら
  • 121. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 121 $a2 1 2 1 0 0 0 0 1 やばい奴ら
  • 122. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 122 $a2 0 2 1 0 0 0 0 1 やばい奴ら
  • 123. 循環参照の GC - MarkGray 矢印を辿りながら ◦ 参照カウントを 1 減らす ◦ 辿ったオブジェクトを「灰色」にする 2015/02/27 第87回 PHP 勉強会 123 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 124. 循環参照の GC - MarkGray 今の状態 ◦ 候補から到達できるオブジェクトは灰色 ◦ 灰色以外からの参照のみカウント 2015/02/27 第87回 PHP 勉強会 124 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 125. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 125 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 126. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 126 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 127. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 127 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 128. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする 2015/02/27 第87回 PHP 勉強会 128 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 129. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ 2015/02/27 第87回 PHP 勉強会 129 $a2 0 1 1 0 0 0 0 1 やばい奴ら
  • 130. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 130 $a2 0 1 1 0 0 0 1 1 やばい奴ら
  • 131. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 131 $a2 0 1 1 0 0 1 1 1 やばい奴ら
  • 132. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 132 $a2 0 1 1 0 0 1 2 1 やばい奴ら
  • 133. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 133 $a2 0 1 1 0 0 1 2 2 やばい奴ら
  • 134. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 134 $a2 0 1 1 0 0 1 2 2 やばい奴ら
  • 135. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 135 $a2 0 1 1 0 0 1 2 2 やばい奴ら
  • 136. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 136 $a2 0 1 1 0 0 1 2 2 やばい奴ら
  • 137. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 137 $a2 1 1 1 0 0 1 2 2 やばい奴ら
  • 138. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 138 $a2 1 1 1 1 0 1 2 2 やばい奴ら
  • 139. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 139 $a2 1 1 1 1 0 2 2 2 やばい奴ら
  • 140. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 140 $a2 1 1 1 1 1 2 2 2 やばい奴ら
  • 141. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 141 $a2 1 2 1 1 1 2 2 2 やばい奴ら
  • 142. 循環参照の GC - ScanBlack 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 142 $a2 1 3 1 1 1 2 2 2 やばい奴ら
  • 143. 循環参照の GC - Scan 矢印を辿りながら ◦ 参照カウントが 0 なら「白」にする ◦ 1 以上なら「黒」にして・・・ ◦ 減らしてしまった参照カウントを戻していく 2015/02/27 第87回 PHP 勉強会 143 $a2 1 3 1 1 1 2 2 2 やばい奴ら
  • 144. 循環参照の GC ゴミなど一つも無かった ◦ 時間の無駄 2015/02/27 第87回 PHP 勉強会 144 $a2 1 3 1 1 1 2 2 2 やばい奴ら
  • 146. ゴミの候補はいつできる? 関数を呼ぶだけでゴミの候補が増える (引数の型による) 2015/02/27 第87回 PHP 勉強会 146 <?php $a = new MyList(); function doSomething($foo) {} doSomething($a);
  • 147. ゴミの候補はいつできる? 関数を呼ぶだけでゴミの候補が増える (引数の型による) 2015/02/27 第87回 PHP 勉強会 147 <?php $a = new MyList(); function doSomething($foo) {} doSomething($a); $a 1 ◦ doSomething 実行前
  • 148. ゴミの候補はいつできる? 関数を呼ぶだけでゴミの候補が増える (引数の型による) 2015/02/27 第87回 PHP 勉強会 148 <?php $a = new MyList(); function doSomething($foo) {} doSomething($a); $a 2 $foo ◦ doSomething 実行中
  • 149. ゴミの候補はいつできる? 関数を呼ぶだけでゴミの候補が増える (引数の型による) 2015/02/27 第87回 PHP 勉強会 149 <?php $a = new MyList(); function doSomething($foo) {} doSomething($a); $a 1 ◦ doSomething 実行後
  • 150. gc_disable() の使いどころ 原則 ◦ 普通は gc_disable() なんて考えなくてよい ◦ メモリリークの元 次のようなプログラムは検討の余地あり ◦ 巨大なグラフ (or 木, リスト, ...) を辿りながら処理する ◦ そのグラフは循環参照によるゴミを出さない 2015/02/27 第87回 PHP 勉強会 150
  • 151. 実験 こんなデータ構造を作って各要素を引数に関数を呼ぶ 2015/02/27 第87回 PHP 勉強会 151 1 ・・・ 1 1 ・・・ 1 1 1 ・・・ ・・・ 配列 リスト
  • 152. 実験 こんなデータ構造を作って各要素を引数に関数を呼ぶ 2015/02/27 第87回 PHP 勉強会 152 1 ・・・ 1 1 ・・・ 1 1 1 ・・・ ・・・ 配列 リスト 配列の要素数によって循環参照の GC が 発生したり発生しなかったりする
  • 153. 実験 プログラム (データ構造を組み立てる部分は省略) 2015/02/27 第87回 PHP 勉強会 153 ... gc_collect_cycles(); $start = microtime(true); for ($i = 0; $i < 10; ++$i) { foreach ($arrayOfList as $list) { doSomething($list); // doSomething は空の関数 } } $end = microtime(true); ◦ $arrayOfList の要素数を変更しながら ($end - $start) を計測 ◦ $list の長さは固定 (100 とした)
  • 154. 実験結果 2015/02/27 第87回 PHP 勉強会 154 PHP 5.6.5 との比較 memory_limit=1024M として実験 Core i5-3337U 1.80GHz
  • 155. 実験結果 2015/02/27 第87回 PHP 勉強会 155 PHP 7.0.0 との比較 memory_limit=1024M として実験 Core i5-3337U 1.80GHz