From what I can see, you code doesn't seem to be wrong...
As a test, I've set up a quick example, with a very simple table (only four fields).
Here is the relevant code :
var_dump(number_format(memory_get_peak_usage()));
$test = Doctrine::getTable('Test')->find(1);
var_dump(number_format(memory_get_peak_usage()));
When doing that, I have this kind of output :
string '1,316,088' (length=9)
string '2,148,760' (length=9)
Considering the table is really simple and that I am only fetching one line, it seems "much" to me too -- but that's quite consistent with what you are getting, and with what I saw on other projects :-(
If you only need to display your data, and not work with it (ie update/delete/...), a solution might be to not fetch complex objects, but only a simple array :
$test = Doctrine::getTable('Test')->find(1, Doctrine::HYDRATE_ARRAY);
But, in this case, it doesn't make much of a difference, actually :-( :
string '1,316,424' (length=9)
string '2,107,128' (length=9)
Only 40 KB of difference -- well, with bigger objects / more lines, it might still be a good idea...
In the Doctrine manual, there is a page called Improving Performance ; maybe it could help you, especially for these sections :
Oh, btw : I did this test on PHP 5.3.0 ; maybe this can have an impact on the amount of memory used...
А откуда такое использование памяти? Как указал Паскаль МАРТИН, гидратация массива не имеет большого значения, что логично, поскольку мы говорим здесь только о нескольких записях.
Потребление памяти происходит от всех классов, которые загружаются по запросу посредством автозагрузки.
Если у вас не настроен APC, то да, что-то не так с тем, как настроена ваша система. Даже не начинайте измерять производительность и ожидать хороших результатов от любой большой библиотеки php без кеша опкодов, такого как APC. Это не только ускорит выполнение, но и уменьшит использование памяти как минимум на 50% при загрузке всех страниц, кроме самой первой (где APC сначала нужно кэшировать байт-коды).
И 4 МБ в вашем простом примере действительно пахнут без APC, иначе он действительно был бы завышен.
I agree with romanb's answer - using an OpCode cache is a definite must when using large libs/frameworks.
An example related to OpCode caching
I've recently adopted Doctrine usage with Zend Framework and was curious about memory usage - so like the OP, I created a method using similar criteria to the OPs test and ran it as an overall test to see what ZF + Doctrine's peak memory usage would be.
I got the following results:
Result without APC:
10.25 megabytes
RV David
16.5 megabytes
Result with APC:
3 megabytes
RV David
4.25 megabytes
Opcode caching makes a very significant difference.
Doctrine предоставляет функцию free() для Doctrine_Record, Doctrine_Collection и Doctrine_Query, которая устраняет круговые ссылки на эти объекты, освобождая их для сборки мусора. Подробнее...
Чтобы сделать использование памяти немного меньше, вы можете попробовать использовать следующий код:
Я бы предположил, что большая часть этой памяти используется для загрузки классов Doctrine, а не для объектов, связанных с самим запросом.
В Doctrine 1.1 поведение автозагрузки по умолчанию называется "агрессивным", что означает, что она загружает все классы вашей модели, даже если вы используете только один или два в любом конкретном запросе. Установка этого поведения на 'консервативное' уменьшит использование памяти.
Я только что выполнил "демонизированный" скрипт с Symfony 1.4, и установка следующих параметров остановила перегрузку памяти:
sfConfig::set('sf_debug', false);