2012-02-12 15 views
0

私はループ内での追加てるの配列を持っている:PHPメモリが使い果たされました - 配列かsql?

array_push($obj->{$type.'listings'}, $listing); 

ループは、リモート呼び出しの束を作り、私は、ファイルに格納し、キャッシュの一種として使用するデータに引っ張ります。

この「キャッシュルーチン」を実行しているときに、この配列をシリアル化すると、わずか5MBを超えることが報告されます。 5MBのアレイを作成するために、スクリプトは100MBのメモリを消費します。可能な限りメモリを解放するための変数を設定しないように非常に注意しています。私は、すべてのコメントを書き、関数のメモリがどこに蓄積されているかを見るためにコメントを外しました。確かに私は配列にプッシュとしてそれが発生します。 array_pushを使用しない場合、memory_get_usage()とgc_collect_cycles()を使用すると、いくつかのスパイクで使用されているかなり安定した量のメモリを見ることができます。

私が配列にプッシュすると、すべてが狂ってしまい、メモリの使用量が増えてしまいます。

このような状況を処理する方法はありますか。

このような大きな配列をPHPで構築することはできませんか?

私はそれを構築している間に配列をファイルにフラッシュする方法はありますか?そして、それをビルドしてファイルに保存できると仮定します。私はそれを使用したいとき、一度ファイルから引っ張られた同じ量のリソースを使用しますか?それは動的に追加されているため、メモリの枯渇が起きているのですか?

これはSQLの使用を検討する必要がありますか?ループの各実行を別々の行に格納していますか?

ちょうどキックのために、私は:ini_set('memory_limit', '-1');を実行するかどうかを確認するために追加しました。

これはありました。メモリ使用量はわずか100MBを超え、シリアル化されたオブジェクトサイズはわずか8MBを超えました。さて、これは私がデータのサンプルを処理していて、これがはるかに大きくなる可能性があるので、実際には役に立ちません。

とにかく、このような状況を最適化する上で考えていることは素晴らしいと思います。

+0

あなたは設定を慎重にしていると言います - あなたはmySQLの結果を解放していますか?あなたが十分なことをすれば、それはあまりにもメモリを吸う傾向があります。 – Westie

+0

私は今のところSQLに何も格納していません。私はそれがより良いルートであるかどうかを尋ねていただけです。しかし、データの取得にはいくつかのSQLクエリがあり、それらを解放するために、結果セットを$ resultに保持するunset($ result)を使用しています。 –

+0

私は決して言いませんでした。私が意図したことは、 'mySQLi_Result :: Free()'やあなたが使っているものを使用していたことです。あなたの要求でunset()がメモリを完全に解放するかどうかは特に分かりません。 – Westie

答えて

0

5MBの配列の場合、PHPは100MBを使用しません。

スクリプトで使用http://it.php.net/memory_get_usageそれは

を成長する場所を確認するには、私は問題なくエントリー数百万のPHP配列(2万円)で構築することを検討してください。 (メモリ使用量が200MB未満)

+0

ええ、まあ、それは私が5MBのシリアル化されたオブジェクトが100MBのメモリを占有していない限り、私が考えたものです。私はmemory_get_usageを使ってこの問題を解決しようとしていますが、配列に追加するだけでそれが成長するようです。これに混乱しています。 –

+0

ここにコードのセクションがあります:http://pastebin.com/8M1Dk73E –

+0

自動改行ではそれほど信じられません – dynamic

-2

数メガバイトのデータを「キャッシュのソート」として使用することは、明らかに悪い考えです。このように無限の原因となる、または無限ループの近くに、

foreach($list AS $value) 
{ 
    $list[] = trim($item); 
} 

あなたが潜在的に無限に$listのサイズを増やすことができます。

+0

大きな配列がキャッシュされている場合は何も問題はありません。 – RobinUS2

+0

ありがとうRobin。データをキャッシュしたい主な理由は、ページが読み込まれるたびにすべてのリモートプロシージャを実行する必要がないことです。だからローカルにデータをキャッシュすることによって...まあ、それはちょうど必要です –

+0

@ RobinUS2ああ確かに間違っていることはありません。多くのメモリと解析のhellovalotを消費することを除いて:) –

0

私はあなたのforeachループを使用している場合にはそのようなリストを通して、あなたを反復することを発見しました。ループを持つスクリプトがより多くのメモリを消費するとき、それは通常、ループが処理するメモリが大きすぎるリストを構築することによって引き起こされます。

関連する問題