akkun_choi pedia
(1722 keywords)

よく使われているタグ

akkun_choiのお気に入り

  • エラー対応 エラー対応
  • 醤油辞典~うまいしょうゆ大好き!醤油マニア デイヴィッドのブック 醤油辞典~うまいしょうゆ大好き!醤油マニア デイヴィッドのブック
  • 阿部道浩の【思いつくままに】百科 阿部道浩の【思いつくままに】百科
  • たけし@読書朝食会Reading-Lab(リーラボ) たけし@読書朝食会Reading-Lab(リーラボ)

akkun_choi pediaのメンバー

  • akkun_choi akkun_choi
  • 西小倉パンデイロ 西小倉パンデイロ
  • tsucchon tsucchon
  • 須田健太郎 須田健太郎

PHP メモリ管理の履歴

調査方法

// 現在のメモリ使用量を知ることができる
echo memory_get_usage();

// メモリの最大量。これを超えると落ちる。
echo ini_get('memory_limit'); 

循環参照をなくすには

case 1 ○

foreach (range(1,1000) as $i){
    $obj = new StdClass;
}

毎回 new してるためメモリが増えそうだが、リファレンスカウントGCのおかげで使われなくなったオブジェクトは解放される。$obj をvar_dumpしてみると、おもしろいことに、#1, #2, #1, #2 と順繰りになっている。

#1が生成→$obj (#1のリファレンスカウントは1)
#2が生成→$obj (#2のリファレンスカウントが1になり、#1が0。よって#1を破棄)
#1が生成→$obj (#1のリファレンスカウントが1になり、#2が0。よって#2を破棄)
...

case 2 ×

foreach (range(1,1000) as $i){                        
    $obj = new StdClass;         // obj1(1)
    $obj->child = new StdClass;  // obj1(1) obj2(1)            
    $obj->child->child = $obj;   // obj1(2) obj2(1)
    unset($obj);                 // obj1(1) obj2(1)
}

循環参照の例。こうするとがメモリっていく。

case 3 ○

foreach (range(1,1000) as $i){                        
    $obj = new StdClass;         // obj1(1)       
    $obj->child = new StdClass;  // obj1(1) obj2(1)            
    $obj->child->child = $obj;   // obj1(2) obj2(1)
    unset($obj->child);          // obj1(1) obj2(0)
}

obj2をunsetすればOK
obj2が破棄されることでobj1への参照もなくなっている?

unset($obj->child); ではなく、unset($obj->child->child); でもOK。
$obj1のリファレンスが0になるから、$obj2もなくなる?

$objというローカル変数を持っていなければならないというのがやっかいなだな。

case 4 ×

class Hoge{
    public $moge;
    function __destruct(){
        unset($this->moge);
    }
}
foreach (range(1,1000) as $i){
    $obj = new Hoge;
    $obj->moge = new Hoge;
    $obj->moge->moge = $obj;
}

destructorとやらを使えばなとかなるじゃね?と思ってやってみたが、だめだった
__destructが呼ばれるのは参照カウントがなくなってかららしい…。

case 5 ○

class Hoge{
    public $moge;
    function destruct(){
        unset($this->moge);
    }
}
foreach (range(1,1000) as $i){
    $obj = new Hoge;
    $obj->moge = new Hoge;
    $obj->moge->moge = $obj;
    $obj->destruct();
}

手動でやればいいだけどさ。case3とたいして変わら。可読性は良くなるけど。今のところこれが最かなぁ。