- 締切済み
PHP 共有メモリについて
PHPのページを作っているのですが、しばらくするとOut of memoryエラーが出ます。 共有メモリを使用しているので、それが原因ではないかと思い、 下記PHP、HTMLのようにしたらOut of memoryエラーが再現しました。 Out of memoryエラーが発生しなくするにはどうしたらいいでしょうか? ■PHP <?php for($i=1;$i<=30;$i++){ $id=shmop_open($i,"c",0666,32*1024*1024); $str=shmop_read($id,0,32*1024*1024); $lpc=0; if(strlen($str)!=0){ $lpc=intval($str)+1; } $len=shmop_write($id,$lpc,0); shmop_close($id); } echo $lpc; ?> ■HTML <html> <head> <meta charset="utf-8" /> <title>a</title> <script> onload=function(){ lp(); } function lp(){ document.ifn.location.href="a.php"; } function ifl(){ setTimeout("lp()",200); } </script> </head> <body> <iframe name="ifn" onload="ifl();"></iframe> </body> </html> ■事象 最初のうちは、iframeでカウントアップされるのですが、しばらくすると Fatal error: Out of memory (allocated 34340864) (tried to allocate 33554433 bytes) in・・・on line 7 とでます。 さらに放置すると、0からカウントアップされる・・・を繰り返します。 ■環境 apache2.2 PHP5.3 memory_limitは128Mにしてあります。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- agunuz
- ベストアンサー率65% (288/438)
ソースのどこにもshmop_deleteがありませんから、残ったままになっていますよね。いつまでも解放されません。 #shmop_closeでは「メモリを解放しない」のは理解されていますよね? #スクリプトから利用するためのハンドルがなくなるだけです すでにある回答で書かれている「ガベージコレクション」はセッションのGCではなく「要らなくなった共有メモリを解放しないとダメ」という意味だと思います(なのでセッションのGC設定は何の意味もありません)。960MB(30 x 32MB)生成してしまうのに「いつ解放するか」をまったく考慮していないのはマズイです。要らなくなった共有メモリを解放する(自分でガベージコレクションする)必要があります。
- tracer
- ベストアンサー率41% (255/621)
どういう用途で、具体的に何をしているのか分かりませんが、phpに対して一回のリクエストでそれだけのメモリを使用してしまうのは、そもそもphpに任せようとしている処理に問題があると思います。仮に不特定多数に公開する内容であれば、どれだけメモリがあっても足りませんね。簡単に言うと、使えるメモリ容量を増やすことを考えるのでなく、使用するメモリ領域を減らす工夫をするほうが現実的かと思います。
お礼
ご回答ありがとうございます。 使用するメモリ量は出来るだけ多くしたいと考えております。 今なら仕様を変更することも可能なので 「使用するメモリ領域を減らす工夫」ではなく 使用できるメモリ領域を大雑把に割り出す計算式等があればそれでもいいのですが・・・。 ご存じないでしょうか?
補足
済みませんお礼の内容が失礼な内容になってしまいました。 以下の文は読み飛ばしていただけたら幸いです。 ”「使用するメモリ領域を減らす工夫」ではなく”
- Tasuke22
- ベストアンサー率33% (1799/5383)
1024x1024x32=32MB 32MBx30=960MB ですねえ… ガーベッジコレクションが必要でしょう。
補足
ご回答ありがとうございます。 ガーベッジコレクションが必要とのことなので php.iniを以下に変更しましたが変わりませんでした(phpinfoで確認済) ・session.gc_divisor = 100(元々から100) ・session.gc_maxlifetime = 100(元々は600) ・session.gc_probability = 100(元々は1) これ以外に確認、修正するべき内容があるでしょうか?
お礼
ご回答ありがとうございます。 同一のメモリを利用していると認識していますので、開放していないことが原因とは思えません。 が、都度、新たにメモリを取りなおしているのかもと思い shmop_deleteを加えてみたのですが、 shmop_delete後のshmop_openでunable to attach or create shared memory segmentになります。 shmop_delete後しばらくは同keyの共有メモリは使えないのでしょうか?