10

Doctrine は、単一の単純なクエリを実行するために 4MB をはるかに超える RAM を使用しているようです。

print memory_get_peak_usage()." <br>\n";
$q = Doctrine_Query::create()
    ->from('Directories d')
    ->where('d.DIRECTORY_ID = ?', 5);

$dir = $q->fetchOne();
print $dir['name']." ".$dir['description']."<br>\n";

print memory_get_peak_usage()." <br>\n";

/***************  OUTPUT:  **************************

6393616
testname testdescription
10999648

/***************************************************/

これは、データがほとんど含まれていないテスト データベース上にあります。照会している項目には、ここに表示されている以外のデータは含まれていません。

システムのセットアップ方法に何か問題がある可能性がありますか?それとも、これは Doctrine の標準的なメモリ使用量ですか?

4

7 に答える 7

6

私が見る限り、あなたのコードは間違っていないようです...


テストとして、非常に単純なテーブル(4 つのフィールドのみ)を使用した簡単な例を設定しました。

関連するコードは次のとおりです。

var_dump(number_format(memory_get_peak_usage()));

$test = Doctrine::getTable('Test')->find(1);

var_dump(number_format(memory_get_peak_usage()));

それを行うと、次のような出力があります。

string '1,316,088' (length=9)
string '2,148,760' (length=9)

テーブルが非常に単純で、1 行しか取得していないことを考えると、それは私にも「多く」のように見えますが、それはあなたが得ているものや、他のプロジェクトで見たものと非常に一致しています :-(


データを表示するだけで、それを操作する必要がない場合 (つまり、更新/削除/...)、解決策は複雑なオブジェクトを取得せず、単純な配列のみを取得することです。

$test = Doctrine::getTable('Test')->find(1, Doctrine::HYDRATE_ARRAY);

しかし、この場合、実際には大きな違いはありません:-( :

string '1,316,424' (length=9)
string '2,107,128' (length=9)

わずか 40 KB の違いです。より大きなオブジェクトやより多くの行を使用しても、それでも良い考えかもしれません...


Doctrine マニュアルには、 Improving Performance というページがあります。多分それはあなたを助けるかもしれません、特にこれらのセクションのために:


ところで、このテストは PHP 5.3.0 で行いました。おそらくこれは、使用されるメモリの量に影響を与える可能性があります...

于 2009-09-11T19:25:05.103 に答える
5

私はromanbの答えに同意します-大きなライブラリ/フレームワークを使用する場合、OpCodeキャッシュを使用することは絶対に必要です。

OpCodeキャッシングに関連する例

最近、Zend FrameworkでDoctrineの使用法を採用し、メモリの使用量に興味がありました。OPと同様に、OPsテストと同様の基準を使用してメソッドを作成し、全体的なテストとして実行して、ZF+Doctrineのピークメモリ使用量を確認しました。なれ。

次の結果が得られました。

APCなしの結果:

10.25 megabytes
RV David
16.5 megabytes

APCでの結果:

3 megabytes
RV David
4.25 megabytes

オペコードキャッシングは非常に大きな違いをもたらします。

于 2009-10-10T05:18:33.777 に答える
4

さて、このメモリ使用量はどこから来たのでしょうか? Pascal MARTIN が指摘したように、配列の水分補給は大きな違いを生むわけではありません。

メモリー消費は、オートロードによってオンデマンドでロードされるすべてのクラスから発生します。

APC が設定されていない場合は、システムの設定方法に問題があります。APC のようなオペコード キャッシュのない大規模な PHP ライブラリで、パフォーマンスの測定を開始して良い結果を期待することさえしないでください。実行速度が向上するだけでなく、最初のページ (APC が最初にバイトコードをキャッシュする必要がある) を除くすべてのページの読み込みでメモリ使用量が少なくとも 50% 削減されます。

そして、あなたの単純な例で4MBは本当にAPCなしのようなにおいがします。そうでなければ、それは本当に少し高くなります。

于 2009-09-28T09:35:56.073 に答える
2

Doctrineは、Doctrine_Record、Doctrine_Collection、およびDoctrine_Queryにfree()関数を提供します。これらの関数は、これらのオブジェクトの循環参照を削除し、ガベージコレクションのために解放します。 より詳しい情報..

メモリ使用量を少し減らすには、次のコードを使用してみてください。

  • $ record-> free(true)–ディープフリーアップを実行し、すべてのリレーションでfree()を呼び出します
  • $ collection-> free()–これによりすべてのコレクション参照が解放されます
  • Doctrine_Manager :: connection()-> clean()/ clear()–接続のクリーンアップ(およびIDマップエントリの削除)
  • $ query-> free()
于 2010-02-21T14:24:45.890 に答える
1

そのメモリのほとんどは、実際にはクエリ自体に関連付けられたオブジェクトではなく、Doctrine のクラスをロードするために使用されると思います。

  • Doctrine のどのバージョンを使用していますか?
  • オートローダーを使用していますか?

Doctrine 1.1 では、デフォルトの autoload 動作は「aggressive」と呼ばれます。これは、特定のリクエストで 1 つまたは 2 つしか使用していない場合でも、すべてのモデル クラスをロードすることを意味します。その動作を「保守的」に設定すると、メモリ使用量が削減されます。

于 2010-03-07T16:22:41.960 に答える
0

symfony 1.4 で「デーモン化された」スクリプトを実行したところ、次のように設定するとメモリの占有が停止しました。

sfConfig::set('sf_debug', false);
于 2010-04-20T13:43:17.817 に答える