Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> тест освобождения памяти, хочу убедиться, что память освобождается 
:(
    Опции темы
ginnie
Дата 9.4.2008, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Уважаемые коллеги!

Допустим в коде есть функция test_func():

Код

sub test_func {
    my ($value_1, $value_2) = @_;
    # просто тестовое условие
    length($value_1) < 200000 or length($value_2) < 200000 ? return 0 : return 1;
}


Нужно удостовериться, что память, занимаемая значениями $value_1 и $value_2 (пусть значения будут длинными, например 500Кб) по окончании вызова функции освобождается (чтобы исключить подозрение, что интерпретатор выделяет память для локальной переменной и не помечает ее как свободную между вызовами).

Хотел бы услышать Ваши предложения по такому тесту.

Это сообщение отредактировал(а) ginnie - 11.4.2008, 21:25


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 9.4.2008, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Может просто попробовать задать значения по 10-20 мегабайт (чтобы невооруженным взглядом было видно) и промониторить память внешней утилитой (top, taskmanager)?

Добавлено через 1 минуту и 13 секунд
в смысле память занимаемую конкретно perl'вым процессом


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
GoDleSS
Дата 9.4.2008, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 11.2.2007
Где: Пироговский

Репутация: 2
Всего: 2



Цитата

Нужно удостовериться, что память, занимаемая значениями $value_1 и $value_2 (пусть значения будут длинными, например 500Кб) по окончании вызова функции освобождается (чтобы исключить подозрение, что интерпретатор выделяет память для локальной переменной и не помечает ее как свободную между вызовами).

Если мне не изменяет память, то как раз в данном случае память и не будет высвобождаться и переменные будут занимать масимальный объем из всех вызовов.
Так что если этот момент критичен - лучше андефить.
--------------------
It's a nice day to die my friend!
PM MAIL WWW ICQ   Вверх
BurnerCode
Дата 10.4.2008, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 28.2.2008
Где: Беларусь

Репутация: нет
Всего: нет



А мне кажеться что память высвобадиться,  ведь эти 2е переменные уничтожаются при выходе из ф-ции.


PM MAIL   Вверх
GoDleSS
Дата 10.4.2008, 09:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 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!
PM MAIL WWW ICQ   Вверх
Bulat
Дата 10.4.2008, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



Насколько я помню, бывало так, что никакие тесты, вообще что-то тривиальное не помогало мне высвобождать память, даже тот же андеф. В случае с большими строками, лучше разбивать все это где нить по 32Kb и работать спокойно. smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
ginnie
Дата 10.4.2008, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Информация для обсуждения:

тестовый скрипт

Код

#! /usr/bin/perl
use strict;
use warnings;

use BSD::Resource;

my $start_usage = getrusage()->maxrss();
my $test = ' ' x 1000000;
warn 'diff1: ', getrusage()->maxrss() - $start_usage, "\n";
test_func($test, '', '');
warn 'diff2: ', getrusage()->maxrss() - $start_usage, "\n";
test_func('', $test, '');
warn 'diff3: ', getrusage()->maxrss() - $start_usage, "\n";
test_func('', '', $test);
warn 'diff4: ', getrusage()->maxrss() - $start_usage, "\n";
test_func2($test, '', '');
warn 'diff5: ', getrusage()->maxrss() - $start_usage, "\n";
test_func2('', $test, '');
warn 'diff6: ', getrusage()->maxrss() - $start_usage, "\n";
test_func2('', '', $test);
warn 'diff7: ', getrusage()->maxrss() - $start_usage, "\n";

sub test_func {
    my ($value_1, $value_2, $value_3) = @_;
    my $lenght = length($value_1) + length($value_2) + length($value_3);
    #undef $value_1;
    #undef $value_2;
    #undef $value_3;
    return $lenght;
}

sub test_func2 {
    my ($value_1, $value_2, $value_3) = @_;
    my $lenght = length($value_1) + length($value_2) + length($value_3);
    #undef $value_1;
    #undef $value_2;
    #undef $value_3;
    return $lenght;
}


результат теста (один из результатов, цифры меняются)

Код

diff1: 2164
diff2: 2880
diff3: 4224
diff4: 5252
diff5: 5968
diff6: 7312
diff7: 8340


теперь раскомментирую строки undef в функциях test_func() и test_func2()

Код

diff1: 2112
diff2: 3144
diff3: 3144
diff4: 3144
diff5: 3144
diff6: 3144
diff7: 3144


Похоже на то, что если явно не делать undef для переменных в функции, то память, занятая переменной не освобождается на случай повторного использования.

Если переменным делать undef, то память освобождается.

Это сообщение отредактировал(а) ginnie - 10.4.2008, 11:48


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 10.4.2008, 11:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



По логике так и должно быть имхо...
Кстати, хотелось бы уточнить: если делать $var = undef, а не undef $var, то память вроде не будет освобождаться. ginnie, если у вас уже есть готовые тесты, не могли бы попробовать такой вариант?


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 10.4.2008, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Тест с использованием

Код

$value_1 = $value_2 = $value_3 = undef;


Код

diff1: 2112
diff2: 3144
diff3: 4172
diff4: 5200
diff5: 6228
diff6: 7184
diff7: 8288



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 10.4.2008, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Как я и думал)


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 10.4.2008, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Не нравится еще вот это:

Код

use strict;
use warnings;

use BSD::Resource;

my $start_usage = getrusage()->maxrss();
my $test = ' ' x 1000000;
warn 'diff1: ', getrusage()->maxrss() - $start_usage, "\n";
if (1) {
    my $test2 = $test;
    warn 'diff2: ', getrusage()->maxrss() - $start_usage, "\n";
}
my $test3 = $test;
warn 'diff3: ', getrusage()->maxrss() - $start_usage, "\n";


Код

diff1: 2080
diff2: 3112
diff3: 4140


Как мне было хорошо, когда я этого не знал!   smile 


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 10.4.2008, 16:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Ну и в очередной раз имхо все логично... Вы просто 3 раза скопировали $test.
А вот если будет так:
Код

my $test = ' ' x 1000000;
...
my $test2 = \$test;
...
my $test3 = \$test;

то такого результата не будет. Во всяком случае я так думаю)


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 10.4.2008, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



KSURi, обращаю Ваше внимание на проблему: она в том, что в примере есть блок if, внутри которого создается локальная переменная и память, занимаемая этой переменной не освобождается после выхода из блока.

В приведенных примерах я копирую несколько раз большой фрагмент для того, чтобы увидеть, освобождается память или нет. Других способов я не знаю. Изначально у нас есть переменная $test, которая содержит текст 1000000 байт.  Далее попадаем в блок if внутри которого создается локальная переменная и инициализируется длинным текстом. По окончании блока переменная уничтожается и память должна освободится (общий объем памяти, используемой скриптом не уменьшается, т.к. интерпретатор свободную память системе не возвращает). Чтобы понять, освободилась память или нет, надо создать еще одну переменную и присвоить ей длинный текст. Если общий объем памяти увеличился - значит при выходе из блока память не освобождается.

Добавлено через 6 минут и 18 секунд
Для уменьшения используемой скриптом памяти (особенно это важно для mod_perl, который я постоянно использую) необходимо в конце использования переменной (массива, хеша) явно делать undef, что мне очень не нравится.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
GoDleSS
Дата 10.4.2008, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 11.2.2007
Где: Пироговский

Репутация: 2
Всего: 2



Цитата

Для уменьшения используемой скриптом памяти (особенно это важно для mod_perl, который я постоянно использую) необходимо в конце использования переменной (массива, хеша) явно делать undef, что мне очень не нравится.

Только в конце пакетов и подпрограмм.
А также в том случае, если на эти переменные/массивы/хеши/и т.д. остались ссылки.
--------------------
It's a nice day to die my friend!
PM MAIL WWW ICQ   Вверх
BurnerCode
Дата 11.4.2008, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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 и не очень сложный smile так что патчим и отсылаем улучшения, так как модуль явно заслуживает внимания.

    * 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
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0809 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.