Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Утечка памяти.


Автор: Валерия 20.9.2009, 16:46
Код

open f, "test.txt";
my @sss = <f>;
close f;

print scalar(@sss) . "\n";
print "Press any key for free memory\n";
<STDIN>;
undef @sss;
print scalar(@sss) . "\n";

print "DONE";
<STDIN>;

В файле пол миллиона строк.
После запуска и загрузки файла процесс занимает в памяти 64 мегабайта (смотрю через диспетчер задач)
После "@sss = undef;" процесс занимает 52 мегабайта.
Собственно, что не освободилось?

Автор: Pfailed 20.9.2009, 17:38
Пытаться что-либо освобождать нужно так:
Код

undef @sss;

Автор: Валерия 20.9.2009, 19:41
Цитата(Pfailed @ 20.9.2009,  17:38)
Пытаться что-либо освобождать нужно так:
Код

undef @sss;

Тож самое.
Мне кажеться что @sss освобождается но не полностью, всё-таки после андефа памяти меньше занимает, но все-равно очень много

Автор: shamber 20.9.2009, 19:44
Валерия, тут уже пробегала темка, о том что память perl, ну очень не любит отдавать.

Автор: KSURi 20.9.2009, 20:06
Интерпретатор не отдает память ОС, а сохраняет ее для последующего использования.

Автор: Pfailed 20.9.2009, 20:09
Процитирую умную книгу (ISBN 5-93286-020-0, стр 113)
Цитата

Чтобы вернуть память в пул памяти процесса, нужно использовать undef(@whatever). Вернуть память в системный пул, вероятно, не удастся, поскольку немногие операционные системы поддерживают это.

Автор: Валерия 20.9.2009, 20:21
А под... Линуксом оно лучше работает?)

Автор: Валерия 20.9.2009, 20:41
Решила свою проблему "в лоб"
Поставила х64 битный perl, теперь памяти могу юзать скок захочу smile

Автор: ginnie 22.9.2009, 12:20
Валерия, извините за бестактность, но Вам 4 Гб в 32-разрядном perl было недостаточно?

Автор: Валерия 23.9.2009, 04:02
Цитата(ginnie @  22.9.2009,  12:20 Найти цитируемый пост)
Валерия, извините за бестактность, но Вам 4 Гб в 32-разрядном perl было недостаточно? 

У меня писало Out of memory когда доходило до, примерно, 1.2 гига занятой оперы.
Не получалось создать более 100 потоков что бы в каждом был LWP...
Теперь 200 легко тянет smile

Автор: ginnie 23.9.2009, 11:35
Валерия, использование скриптом 1,2 Гб памяти для меня бы послужило признаком, что я что-то делаю не так. Не пробовали заменить потоки на event loop (например, использовать EV)?

Автор: Валерия 24.9.2009, 22:43
Цитата(ginnie @  23.9.2009,  11:35 Найти цитируемый пост)
Валерия, использование скриптом 1,2 Гб памяти для меня бы послужило признаком, что я что-то делаю не так. Не пробовали заменить потоки на event loop (например, использовать EV)? 

Что за event loop такие?

Автор: ginnie 25.9.2009, 00:11
Событийная машина (event loop) позволяет реализовать асинхронную передачу данных для нескольких соединений в рамках одного процесса. Самый быстрый модуль, с которым я имел дело - EV. Суть событийной машины в следующем. Предположим нам надо получить данные от двух серверов. Стандартно это делается так: соединяемся с первым сервером, посылаем запрос, получаем ответ, закрываем соединение, соединяемся со вторым сервером... В случае если соединение установить невозможно, программа будет ожидать до истечения таймаута. Если использовать событийную машину, то алгоритм будет таким: открываем сокет к первому серверу в неблокируемом режиме (не дожидаясь соединения) и создаем функцию-обработчик записи в сокет, открываем сокет ко второму серверу в неблокируемом режиме и создаем функцию-обработчик записи в сокет, создаем таймер для завершения обработки по истечении таймаута (можно задать отдельные таймеры для каждого соединения, по желанию). Запускаем цикл обработки событий. После установления соединения с одним из серверов будет вызвана соответствующая функция-обработчик. Например, для первого сервера. Внутри этой функции мы выполняем запрос к удаленному серверу и создаем функцию-обработчик чтения из сокета, после завершения функции-обработчика записи управление передается обратно в цикл обработки событий (во время выполнения функции-обработчика другие события не обрабатываются, т.к. у нас один поток выполнения). После ответа первого сервера на наш запрос вызывается функция-обработчик для чтения, в которой мы получаем данные из сокета и сохраняем их (или обрабатываем). После получения всех данных закрываем соединение. Функция-обработчик чтения вызывается по мере получения данных от сервера многократно. После получения всех данных от сервера закрываем соденинение. После закрытия всех соединений (или срабатывания таймера) завершаем цикл обработки сообщений.

Сама идея событийной машины проста, но при реализации возникают некоторые сложности. В основном они связаны с передачей данных в функции-обработчики (очень часто это делается при помощи замыканий, что делает код непрозрачным). Дмитрий Карасик сделал попытку упростить использование событийной машины при помощи модуля IO::Lambda, но я, к своему стыду, не сподобился им попользоваться, т.к. все, что было нужно написал на EV.

Автор: gcc 25.9.2009, 01:41
на FreeBSD говорят многопоточность - вчеращний день 

там есть kevent, как-то я ядром работает 
http://search.cpan.org/~msergeant/IO-KQueue-0.32/KQueue.pm
http://www.opennet.ru/base/dev/kevent_freebsd.txt.html

полезно для сокетов (создание нового потока для каждого сокета дорогая операция для ОС) или например для программы которая бы реагировала на изменения в файле

может оно лучше будет?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)