4

配列内の何千ものアイテムを foreach し、いくつかの操作を行い、いくつかの値を mysql テーブルに保存しようとしています。

ただし、ループを繰り返すと、php.ini で指定したメモリが不足するまで、メモリ使用量が増え続けます。これは非常に高速です。

unset を使用して変数を null に設定し、ガベージ コレクションを調べましたが、何も影響はありません。

これらの要素をループできるより効率的な方法はありますか (つまり、メモリ使用量が継続的に増加しないようにするため)。

以下は、私がやっていることの簡単な例です。

foreach ($subscribers as $subscriber)
{
    $member = new Member($subscriber['id']);
    if ($member['id'] > 0)
    {
        $bulletin = Bulletin::getCustomBulletin($member['id']);

        Bulletin::compileBulletin($member['email'], time(), $bulletin['title'], $bulletin['content']);

        echo $member['email'] . "\n";
        echo memory_get_usage() . "\n";
    }
}

これにより、次の結果が生成されます。

an@email.com
11336688
an@email.com
12043640
an@email.com
12749952
4

3 に答える 3

2

$suscribersDBクエリの結果ですか?

その場合、それが問題の原因である可能性があります。一度に 1 つずつ処理しても、行がメモリにバッファリングされます。

バッファリングされていないクエリを使用するか、クエリの結果の数を制限していくつかの小さなクエリを実行できます。

参照: 「許可されたメモリサイズが使い果たされた」のはなぜですか?

于 2012-04-24T15:21:00.763 に答える
0

あなたのforeachループについて疑わしいものは何もありません(各反復ですべて上書きされているため、設定を解除する変数はありません)。メモリ グラブの原因となっている行を特定する必要があります。これには、プロの IDE にあるプロファイラーが役立ちます。1つにアクセスできない場合は、これまでと同じように使用するmemory_get_usage()必要がありますが、各行の後に配置して、ボトルネックを引き起こしているものを確認してください.

xdebugなどの無料のプロファイリング ツールもあります。

于 2012-04-24T15:15:38.617 に答える
0

残念ながら、Member オブジェクトが内部で何を行っているかについての手がかりがないため、投稿したコードからはわかりにくいですが、これは可能性があるようです:

再帰参照によるメモリリーク

上記のコードで新しいメンバー オブジェクトの作成を削除して、それがメモリ リークの原因であるかどうかを確認します。あなたが言ったことから、メンバーオブジェクトの作成はとにかく不要かもしれませんし、静的なルックアップメンバー関数に置き換えることができます.

于 2012-04-24T15:30:47.657 に答える