More Related Content
Similar to PHP の GC の話 (20)
PHP の GC の話
- 4. 自己紹介
内山 雄司
◦ 株式会社ピコラボ
◦ @y__uti
◦ http://y-uti.hatenablog.jp
好きな話題
◦ 機械学習とその周辺分野(ほぼ仕事)
◦ 楽しいけれど数学は不真面目だったので色々つらい
◦ プログラミング言語処理系(学生のときの研究分野/今は趣味)
◦ 去年あたり?から HHVM とか PHP7 とか盛り上がっていて楽しい
◦ PHP dis
2015/02/27 第87回 PHP 勉強会 4
- 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
- 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
- 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
- 31. array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 31
$a1
←もう使わない
- 33. array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 33
$a1
←もう使わない
- 35. array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 35
$a1
←もう使わない
- 37. array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 37
$a1
←もう使わない
- 39. array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 39
$a1
←もう使わない
- 41. array(1, 2, ..., 200000)
array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 41
$a1
←もう使わない
- 43. array(1, 2, ..., 200000)
PHP には GC があるので
2015/02/27 第87回 PHP 勉強会 43
$a1
Happy!
- 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
◦ 無理
- 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
これは?→
- 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
やばい奴ら
- 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
やばい奴ら
- 150. gc_disable() の使いどころ
原則
◦ 普通は gc_disable() なんて考えなくてよい
◦ メモリリークの元
次のようなプログラムは検討の余地あり
◦ 巨大なグラフ (or 木, リスト, ...) を辿りながら処理する
◦ そのグラフは循環参照によるゴミを出さない
2015/02/27 第87回 PHP 勉強会 150
- 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 とした)