$beforeCreate = memory_get_usage();
//Создаем объект ActiveRecord
$mailer = Mailer::findOne(20);
//Удаляем объект из памяти
unset($mailer);
$afterDelete = memory_get_usage();
по идее объем используемой памяти до создания объекта и после его удаления должен совпадать: $beforeCreate = $afterDelete,
однако на деле получаем: $beforeCreate < $afterDelete.
Почему unset не освобождает память,выделенную под объект?
Как тогда освободить эту память?
// comment out the following two lines when deployed to production
//defined('YII_DEBUG') or define('YII_DEBUG', true);
//defined('YII_ENV') or define('YII_ENV', 'dev');
yan писал(а):и что так сильно много памяти расходуется? попробуйте несколько раз сделать тоже самое - подозреваю память расходуется только в первый раз
Нет, "утекающая" память накапливается после каждого обращения.
В итоге затрудняется работа с большими объемами данных.
Суть в том, что там нужно доставать Over 300 000 записей, естесвенно это все делается пачками, таким образом как-раз и планировалось избежать любых проблем с памятью.
Только беда в том, что когда в цикле достаем записи, они копятся в оперативной памяти.
unset переменных, в которые были получены данные ActiveRecord, не приводит ни к чему толковому.
Тоесть ссылка(переменная) удаляется, а сами данные остаются, и при этом копятся...
Самое лучше, что вы можете сделать это unset($mailer);
Этот вызов означает, что $mailer удалится, но память не высвободится. Всё потому, что mailer это по сути ссылка на контейнер в памяти. На этот контейнер ссылаются Mailer атрибуты.
Всё само очистится, только когда скрипт завершится - по другому в php "утекающую память" не высвободить.
Переход на array не решит проблему утечки памяти, просто меньше будет её использоваться. Но утечка имеет место быть, при unset и ничего с этим не поделать :) Если вы упёрлись в лимит, то нужно изменять логику отдельных участков приложения.
yiijeka писал(а):
Переход на array не решит проблему утечки памяти, просто меньше будет её использоваться. Но утечка имеет место быть, при unset и ничего с этим не поделать
с массивами все таки утечка намного меньше получается по опыту
vismut писал(а):Суть в том, что там нужно доставать Over 300 000 записей, естесвенно это все делается пачками, таким образом как-раз и планировалось избежать любых проблем с памятью.
Только беда в том, что когда в цикле достаем записи, они копятся в оперативной памяти.
unset переменных, в которые были получены данные ActiveRecord, не приводит ни к чему толковому.
Тоесть ссылка(переменная) удаляется, а сами данные остаются, и при этом копятся...
Помнится в книге PHP5 Котерова, была такая рекомендация: чтобы удалить переменную, то нужно было сначала присвоить ей пустое значение, а потом вызывать unset.
yiijeka писал(а):
Самое лучше, что вы можете сделать это unset($mailer);
Этот вызов означает, что $mailer удалится, но память не высвободится. Всё потому, что mailer это по сути ссылка на контейнер в памяти. На этот контейнер ссылаются Mailer атрибуты.
$beforeCreate = memory_get_usage();
//Создаем объект
$object = new SomeClass;
//Удаляем объект из памяти
unset($object );
$afterDelete = memory_get_usage();
все равно получаем утечку $beforeCreate < $afterDelete
//Создаем объект
$object = new SomeClass;
$beforeCreate = memory_get_usage();
//Удаляем объект из памяти
unset($object );
$afterDelete = memory_get_usage();
Но там все равно будет разница. От этого не уйти. Никто, кроме самого php, не сможет очистить память. PHP выполняет очистку памяти автоматически. Вы не сможете явно удалить из памяти что-то. Вы сможете только поставить в очередь на удаление - это и есть unset() в вашем случае.
в принципе unset очищает память практически полностью, оставляя какие-то крохи байт где-то на поддерживающие механизмы (проверил на 5.5)
запустил в цикле $object = new SomeClass(); unset($object); память вообще ни как не растет по ходу цикла
кстати, присвоение null вообще ни как не помогает, хотя в предыдущих версиях может и помогала...
наверное вам стоит проверить свое приложение, и большая утечка где-то еще
может быть даже фреймворк где-то сжирает, тут вам уже надо пошагово проверять увеличение помяти в кодах фреймворка...
astronin писал(а):в принципе unset очищает память практически полностью, оставляя какие-то крохи байт где-то на поддерживающие механизмы (проверил на 5.5)
запустил в цикле $object = new SomeClass(); unset($object); память вообще ни как не растет по ходу цикла
кстати, присвоение null вообще ни как не помогает, хотя в предыдущих версиях может и помогала...
наверное вам стоит проверить свое приложение, и большая утечка где-то еще
может быть даже фреймворк где-то сжирает, тут вам уже надо пошагово проверять увеличение помяти в кодах фреймворка...
Пример с простым объектом не актуален)
Лучше сделайте так и скажите что тоже не растет)