Nucleus

NP_UnsetItemObject

2007年5月7日

方々で、Nucleusはメモリ食いだと議論されている様子。$manager->getItem() がやり玉にあがっている。もし、MANAGERオブジェクトにITEMオブジェクトが蓄積されていくのがその原因なのであれば、次のようなプラグインでそれが解消できるかもしれない。このプラグインは無効のため、別のプラグインを書いてみた。

削除しました。

PostItemイベントを捕まえて、一つ前のitemオブジェクトを廃棄する仕様。テンプレート呼び出しで多数のアイテムが呼び出される場合には、効果的かもしれない。私が管理しているサイトで、700個以上のitemオブジェクトが作成されるものがあるから、それにインストールして様子を見てみる。

(追記)ver 0.1 は、意味のないコードだったので、若干修正。ver 0.1.1とした。

(追記)このコードの効果を確認するためのテストを行った。

(追記)このコードは、意味がなかった…。もっとよく考えてみることにしよう。



テストには、以下のスクリプトを使用。6行目を書き換えて、異なる5つの条件で、メモリ使用量を測定した(Windows XP/Apache2.0/PHP4.4)。
<?php

include('./config.php');

$mode=array(0=>'control',1=>'none',2=>'unset',3=>'false',4=>'both');
$mode=$mode[0];
for ($i=0;$i<1000;$i++){
    echo $i,' ';
    $manager2[$i]=new MANAGER;
    switch($mode){
    case 'control':
        //$item=&$manager2[$i]->getItem(1,false,false);
        //$item=false;
        //unset($manager2[$i]->items[1]);
        break;
    case 'none':
        $item=&$manager2[$i]->getItem(1,false,false);
        //$item=false;
        //unset($manager2[$i]->items[1]);
        break;
    case 'unset':
        $item=&$manager2[$i]->getItem(1,false,false);
        //$item=false;
        unset($manager2[$i]->items[1]);
        break;
    case 'false':
        $item=&$manager2[$i]->getItem(1,false,false);
        $item=false;
        //unset($manager2[$i]->items[1]);
        break;
    case 'both':
        $item=&$manager2[$i]->getItem(1,false,false);
        $item=false;
        unset($manager2[$i]->items[1]);
        break;
    default:
        break;
    }
}
$api=new COM("SfcMini.DynaCall");
$api->Declare("user32","MessageBoxA");
$api->sfc_null(0,"Click OK to finish.","test",0);
?>

使用量は、ダイアログが表示されているときのApacheのメモリ使用量を、『OK』ボタンをクリックした後の使用量から差し引いた値として求めた。結果は、以下のとおり。

control: 6816K
none: 21204K
unset: 7124K
false: 7160K
both: 7072K
both: 7076K
false: 7180K
unset: 7088K
none: 21196K
control: 6812K

上から順に測定を行い、それぞれ2回測定した。すべての計測を終えるのに、約10分を費やした。2回の平均を取り、control のメモリ使用量(MANAGERオブジェクト作成分に相当)を差し引いて、一つの記事辺りのメモリ使用量を計算した値が、以下のとおり。なお、itemid=1 は、おなじみの『Nucleus CMS バージョン3.2へようこそ』である。

none: 14387 bytes
unset: 293 bytes
false: 357 bytes
both: 261 bytes

$manager->items[n] を直接 unset しても、false値を代入しても、それほど大きな違いは見られなかった。false値を保存しておくのに、64 bytes 費やしているように思われる。both では unset より若干メモリ使用量が少ないという結果が得られたが、おそらく実験の誤差によるものであろう。

unset を行うには、$manager オブジェクトのプロパティに直接アクセスする必要がある。プロパティの名称は、今後のNucleusのバージョンでは異なる可能性がある。コアのアップグレードに備えてfalse値を代入する方法を用いることが現実的だと思う。

それにしても1つのアイテムあたり14 Kbytesも消費することがあるわけだから、700個のアイテムを表示すると合計10Mbytesになる。これはやはり、対策をしておいたほうが良いだろう。環境によっては、上記のプラグインを導入することで、かなりの効果が期待できる。

コメント

コメントはありません

コメント送信