がるの健忘録

エンジニアでゲーマーで講師で占い師なおいちゃんのブログです。

(主としてメモリ関連とかの)小枝

んと…ちょいと気付いたりした小枝ぢゃなくて小技各種。


いち。
ぶっちゃけ、奇妙なライブラリやOSSの類の「ムダなエラー抑止演算子」が最近邪魔でたまりません(とかいうMWにもあるので…消さないとねぇ)。
だって。出力はあとで error_reporting( http://d.hatena.ne.jp/gallu/20090423/p1 )で制御すりゃいいっしょ?
っつわけで、これ。
http://jp.php.net/manual/ja/scream.examples-simple.php

ini_set('scream.enabled', false);

「エラー抑制演算子の無効化」という、ど真ん中クリティカルヒットな感じのものがありますw
上手に使いましょう。特に面倒な現場で orz


に。
gc_collect_cycles。
すべての既存ガベージサイクルを強制的に収集するって事で…危なそうでもあり、便利そうでもあり。
…だれか実験したひと、いません?w
# (PHP 5 >= 5.3.0)、だからなぁ…


さん。
memory_get_peak_usage & memory_get_usage。
いずれも「PHP君が食い倒しているメモリ量を出力」するです。
前者が「最大値」、後者が「現在値」を示します。
memory_get_peak_usageに関しては、正直引数をfalse(省略値)にする意味がわからんです。なので、可能な限りtrueを。
memory_get_usageの場合「関数のチューニング」ならfalseもある程度あり。ただ現実問題としてシステムに対してなにがしか影響を及ぼすのは結局「今、ガメてるメモリ量」なので。やっぱりtrueのほうが「もあべたぁ」だと思う。


で…どうも、デフォで256k(多分コンパイルオプションその他で変動すると予想。おいちゃんの環境の場合です)は絶対確保するみたい。
なにせ

<?php

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );

の結果が

int(51616)
int(262144)
int(47292)
int(262144)

ですから。


面白いのが、もうちょっと負荷をかけた時(少なくとも以前は、PHPのガベコレが大分腐ってたので…システム自体に圧をかけた場合に同じようになるかは不明)。

<?php
require_once('/opt/www/mw.conf');

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";
$s = 'aaaa( aを1万文字 )';

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

$s = ''; unset($s);

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

$s = file_get_contents( てけとうなサイトのURI );

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

$s = '';

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

unset($s);

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

$a = array();
for($i = 0; $i < 10000; $i ++) {
  $a[] = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
}

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

$a = array();

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

unset($a);

var_dump( memory_get_peak_usage() );
var_dump( memory_get_peak_usage(true) );
var_dump( memory_get_usage() );
var_dump( memory_get_usage(true) );
print "-----------\n";

コピペ連打なのは気にすんない。色々試しながらここまでふくれたんだw
んで、これの結果。

int(105488)
int(262144)
int(71760)
int(262144)

                    • -

int(105488)
int(262144)
int(81844)
int(262144)

                    • -

int(105488)
int(262144)
int(71760)
int(262144)

                    • -

int(107188)
int(262144)
int(89412)
int(262144)

                    • -

int(107188)
int(262144)
int(73272)
int(262144)

                    • -

int(107188)
int(262144)
int(73184)
int(262144)

                    • -

int(1940240)
int(2097152)
int(1939004)
int(2097152)

                    • -

int(1940312)
int(2097152)
int(73416)
int(524288)

                    • -

int(1940312)
int(2097152)
int(73256)
int(524288)

                    • -

とりあえず。リファレンスカウンタ切るなりunsetなりがそれなりに有効に働いている事が確認できます。
とはいえ基本メモリは「ブロック単位で切り出している」ようなので、あんまりこまめなごにょごにょがどれくらい意味があるのかはこれからの実験と検証を待つ必要がありますw
まぁ。色々と使えるところではないでしょうか?


おまけ。
えと…おいちゃんが想定している使い方。
1.「なんか1区画(クラスとか関数とか)で妙にメモリ食い倒してる気がする」
memory_get_usageを、引数falseとtrueの双方で取ってください。
その辺をロギングすると、分析の役に立ちます多分。


2.落ちる orz
プログラムのラストのほうでmemory_get_peak_usageをtrueで叩いてください。
どれくらい贅沢で潤沢でムダなメモリ使いをしているのかが一撃でわかります orz


さて…Weponのロギング機能に memory_get_peak_usage くらいはぶち込んでおくかな。