![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемые коллеги!
Допустим в коде есть функция test_func():
Нужно удостовериться, что память, занимаемая значениями $value_1 и $value_2 (пусть значения будут длинными, например 500Кб) по окончании вызова функции освобождается (чтобы исключить подозрение, что интерпретатор выделяет память для локальной переменной и не помечает ее как свободную между вызовами). Хотел бы услышать Ваши предложения по такому тесту. Это сообщение отредактировал(а) ginnie - 11.4.2008, 21:25 -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
| KSURi |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Может просто попробовать задать значения по 10-20 мегабайт (чтобы невооруженным взглядом было видно) и промониторить память внешней утилитой (top, taskmanager)?
Добавлено через 1 минуту и 13 секунд в смысле память занимаемую конкретно perl'вым процессом -------------------- Died at Life.pl line 21 |
|||
|
||||
| GoDleSS |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 105 Регистрация: 11.2.2007 Где: Пироговский Репутация: 2 Всего: 2 |
Если мне не изменяет память, то как раз в данном случае память и не будет высвобождаться и переменные будут занимать масимальный объем из всех вызовов. Так что если этот момент критичен - лучше андефить. --------------------
It's a nice day to die my friend! |
|||
|
||||
| BurnerCode |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 37 Регистрация: 28.2.2008 Где: Беларусь Репутация: нет Всего: нет |
А мне кажеться что память высвобадиться, ведь эти 2е переменные уничтожаются при выходе из ф-ции.
|
|||
|
||||
| GoDleSS |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 105 Регистрация: 11.2.2007 Где: Пироговский Репутация: 2 Всего: 2 |
BurnerCode, почитайте пожалуйста тему http://forum.vingrad.ru/forum/topic-201623/view-all.html
--------------------
It's a nice day to die my friend! |
|||
|
||||
| Bulat |
|
|||
![]() татарский Нео ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1701 Регистрация: 22.3.2006 Где: Альметьевск Репутация: 5 Всего: 57 |
Насколько я помню, бывало так, что никакие тесты, вообще что-то тривиальное не помогало мне высвобождать память, даже тот же андеф. В случае с большими строками, лучше разбивать все это где нить по 32Kb и работать спокойно.
-------------------- менеджер по кодеврайтингу |
|||
|
||||
| ginnie |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Информация для обсуждения:
тестовый скрипт
результат теста (один из результатов, цифры меняются)
теперь раскомментирую строки undef в функциях test_func() и test_func2()
Похоже на то, что если явно не делать undef для переменных в функции, то память, занятая переменной не освобождается на случай повторного использования. Если переменным делать undef, то память освобождается. Это сообщение отредактировал(а) ginnie - 10.4.2008, 11:48 -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
||||||
|
|||||||
| KSURi |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
По логике так и должно быть имхо...
Кстати, хотелось бы уточнить: если делать $var = undef, а не undef $var, то память вроде не будет освобождаться. ginnie, если у вас уже есть готовые тесты, не могли бы попробовать такой вариант? -------------------- Died at Life.pl line 21 |
|||
|
||||
| ginnie |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Тест с использованием
-------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
||||
|
|||||
| KSURi |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Как я и думал)
-------------------- Died at Life.pl line 21 |
|||
|
||||
| ginnie |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Не нравится еще вот это:
Как мне было хорошо, когда я этого не знал! -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
||||
|
|||||
| KSURi |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Ну и в очередной раз имхо все логично... Вы просто 3 раза скопировали $test.
А вот если будет так:
то такого результата не будет. Во всяком случае я так думаю) -------------------- Died at Life.pl line 21 |
|||
|
||||
| ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
KSURi, обращаю Ваше внимание на проблему: она в том, что в примере есть блок if, внутри которого создается локальная переменная и память, занимаемая этой переменной не освобождается после выхода из блока.
В приведенных примерах я копирую несколько раз большой фрагмент для того, чтобы увидеть, освобождается память или нет. Других способов я не знаю. Изначально у нас есть переменная $test, которая содержит текст 1000000 байт. Далее попадаем в блок if внутри которого создается локальная переменная и инициализируется длинным текстом. По окончании блока переменная уничтожается и память должна освободится (общий объем памяти, используемой скриптом не уменьшается, т.к. интерпретатор свободную память системе не возвращает). Чтобы понять, освободилась память или нет, надо создать еще одну переменную и присвоить ей длинный текст. Если общий объем памяти увеличился - значит при выходе из блока память не освобождается. Добавлено через 6 минут и 18 секунд Для уменьшения используемой скриптом памяти (особенно это важно для mod_perl, который я постоянно использую) необходимо в конце использования переменной (массива, хеша) явно делать undef, что мне очень не нравится. -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
| GoDleSS |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 105 Регистрация: 11.2.2007 Где: Пироговский Репутация: 2 Всего: 2 |
Только в конце пакетов и подпрограмм. А также в том случае, если на эти переменные/массивы/хеши/и т.д. остались ссылки. --------------------
It's a nice day to die my friend! |
|||
|
||||
| BurnerCode |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 37 Регистрация: 28.2.2008 Где: Беларусь Репутация: нет Всего: нет |
оригинал тут: http://xpoint.ru/know-how/Perl/UtechkiPamyati?5
Модули: * Devel::Leak::Object - Специально для объектно-ориентированных программ, но просто незаменим. Наверное самое большое преимущество этого модуля в возможности отслеживать как все классы, так и отдельную группу. Модуль переопределяет функцию bless и DESTROY, а при выходе из программы выдает список объектов, которые не были уничтожены и трассировку стека в том месте программы, где объект был создан. Дальше обычно много легче самому проверить логику программы от точки создания объекта. Для работы всех этих вкусностей нужны патчи: http://rt.cpan.org/Ticket/Display.html?id=21145. Есть еще глюки и дока не очень, нокод pure perl и не очень сложный * Devel::Cycle - принимает ссылку и ищет циклы внутри. Полезно, когда вы знаете, что цикл внутри, но не найдет проблему если кто-то ссылается на этот объект снаружи. o Test::Memory::Cycle - несколько простых функци для использования в тестах на утечки памяти (использует Devel::Cycle). После того как вы избавились от цкилических ссылок в какой-то группе структур в вашей програме, вы пишете несколько тестов, которые проверябт что это так, что позволит вам быть частично уверенным, что больше этого не повторится. * Devel::FindRef - неплохой модуль, хоть и немного сыроват, но может помочь найти ссылки на объект, когда вы точно знаете, что объект не уничтожается, а внутри цикла нет. Например вы сохранили ссылку в глобальной переменной пакета. Это модуль можно использовать для написания модуля поиска циклов в переменных, которые ссылаются на текущую структуру. * Devel::Monitor * Object::Destroyer * Devel::ObjectTracker * Devel::GC::Helper * Devel::Leak * Devel::LeakTrace, Devel::LeakTrace::Fast - эти два модуля использую возможность perl устанавливать дополнительный обработчик на каждый оператор, что достаточно сильно замедляет выполнение, но позволяет отследить все на самом низком уровне. Второй модуль и правда быстрее так как на большом проекте я (Руслан) просто не дождался запуска сервера с первым модулем, но все равно скорость оставляет желать лучшего. * Devel::Size * Devel::DumpSizes * Devel::Size::Report * Devel::Arena Это сообщение отредактировал(а) BurnerCode - 11.4.2008, 08:38 |
|||
|
||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |