Xpoint
   [напомнить пароль]

Освобождение памяти после цикла

Метки: [без меток]
[удл]
2009-03-11 20:54:07 [обр] gal7[досье]
Как в таком примере сделать так, чтобы при выходе из цикла память, отведенная ему автоматически освобождалась (знаю только про undef(), но может еще чем-то можно пользоваться)? Хотел бы узнать почему она не освобождается при выходе из цикла? Где то тут видимо есть скрытые ссылки, но я их не вижу.
for(my $n = 0;$n < 1;$n++){
   my $fayl = "a.pl";
   open(my $deskr_fayla, "<", $fayl);
   read($deskr_fayla, my $a, 1, 100000000);
   close($deskr_fayla);
}
sleep(5);
спустя 52 минуты [обр] Евгений Седов aka KPbIC(38/176)[досье]
Как вы определили, что память не освободилась?
спустя 7 часов [обр] Роман Чемисов(56/327)[досье]
gal7[досье]
Освободить память для операционной системы не получится. При undef() память освобождается только для процесса perl.
спустя 4 часа 51 минуту [обр] gal7[досье]
Я смотрю на количество свободной оперативной памяти-после выхода из цикла ее становится на 100 мб меньше (пока sleep идет это видно). Если же в конце итерации ставлю undef($a), то эти 100 мб после цикла свободны ($a-это тестовая переменная чтобы сразу был виден отъем памяти сделал ее большой).
спустя 33 минуты [обр] Евгений Седов aka KPbIC(38/176)[досье]

Вы все делаете правильно.

Имейте в виду, что уже существуют глобальные $a и $b perldoc -f sort.

спустя 55 минут [обр] Евгений Седов aka KPbIC(38/176)[досье]

Теперь я кажется понял, о чем вы говорите.

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

my $file = 'text';
{
    open(my $fd, '<', $file);
    read($fd, my $buf, 1, 100000000);
    close $fd;
}
sleep(10);

open (my $fd2, '<', $file);
read($fd2, my $buf2, 1, 100000000);
close $fd2;
sleep(10);

Почему процесс забирает 2 раза по 100? Ответа не знаю.

спустя 16 минут [обр] Евгений Седов aka KPbIC(38/176)[досье]
Вот, статьяна эту тему.
спустя 18 минут [обр] gal7[досье]

Да, эту статью я читал, но на данный вопрос не смог найти ответа.
Пробую так:

{
   my $text = "1";
   $text x= 100000000; 
}

Тоже самое. Видимо где то тут остаются невидимые ссылки, и из-за этого переменные не уничтожаются при выходе из блоков, но где я не вижу.

спустя 22 минуты [обр] Евгений Седов aka KPbIC(38/176)[досье]

gal7[досье] Как написано в статье:

Эта тонкая проблема, по-видимому, связана с механикой переотведения памяти в Perl.

Боюсь, что никаких скрытых ссылок в этих 2-ух строках вам никто не найдет.
Делайте undef перед выходом из блока, этот же вариант у вас работает?

спустя 13 минут [обр] Алексей Севрюков(198/1280)[досье]

Статья конечно ничего, вот только в ней описаны проблемы версий 5.5 и 5.6, лично я даже 5.6 версии перестал видеть еще год-два назад, у большинства хостеров стоит минимум 5.8, у разработчиков вообще скорее всего 5.10.

Насчет undef переменных в локальной области видимости - ИМХО, может быть и актуально для тех версий, но это явный бред. Полагаю что Perl GC срабатывает все-таки не моментально и не вызывается сразу при выходе из блока, в связи с этим память и остается "занятой".

Хотя с другой стороны, приведенные выше пример с чтением из двух файлов настараживает. На какой системе проводилось тестирование, какой версии Perl?

спустя 11 минут [обр] Евгений Седов aka KPbIC(38/176)[досье]
eugenio@bedouin~:$ perl --version | head -n4

This is perl, v5.10.0 built for i486-linux-thread-multi

Copyright 1987-2007, Larry Wall
спустя 3 минуты [обр] Евгений Седов aka KPbIC(38/176)[досье]
eugenio@bedouin~:$ uname -a
Linux bedouin 2.6.27.7-smp #1 SMP Wed Mar 11 10:18:08 MSK 2009 i686 Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz GenuineIntel GNU/Linux
спустя 10 минут [обр] Евгений Седов aka KPbIC(38/176)[досье]
gal7[досье]В последнем случае (когда не из файла читаем, а умножаем строку), расход памяти еще в 2 раза больший.
спустя 17 минут [обр] Евгений Седов aka KPbIC(38/176)[досье]
С таким названием темы, может быть в женском журнале помощи попросить?
спустя 29 минут [обр] gal7[досье]

>В последнем случае (когда не из файла читаем, а умножаем строку), расход памяти еще в 2 раза больший.
У меня все также - каждая такая конструкция отнимает ~100 Mb.
ОС windows XP.

>С таким названием темы, может быть в женском журнале помощи попросить?
:) Да уж, погорячился.
Кстати сейчас заметил, что если вместо my использовать local, то память освобождается нормально. Может быть в этом решение? Буду испытывать.

спустя 17 минут [обр] Евгений Седов aka KPbIC(38/176)[досье]

local это не изящно, при use strict вам придется объявлять все такие переменные глобальными. Если Алексей Севрюков[досье] подтвердит, что статья с opennet.ru до сих пор актуальна, то использование undef в конце блока, IMHO, выглядит логичнее.

К тому же, мы помним, что применение этого метода необходимо только для "тяжелых" перменных.

спустя 32 минуты [обр] Алексей Севрюков(198/1280)[досье]
Евгений Седов aka KPbIC[досье] да Вы уже сами все подтвердили тем, что в 5.10 тот же самый глюк.
спустя 6 дней [обр] Green(3/6)[досье]

Это совсем не глюк, хотя очень похож на него.
Года 1,5 назад я заметил это поведение http://mail.pm.org/pipermail/moscow-pm/2007-December/000615.html
Перл резервирует память для каждого блока кода(этот блок ещё называют чанкой).
Такой подход обусловлен тем, что инициализация чанки требует существенно большего времени, чем её повторное использование.

P.S. Не могу назвать себя экспертом, но некоторое понимание происходящих процессов у меня есть, так что если есть интерес, могу описать то, что происходит.

спустя 8 часов [обр] Евгений Седов aka KPbIC(38/176)[досье]
Green[досье]Аудитория у ваших ног.
спустя 1 день 8 часов [обр] Green(3/6)[досье]

Рассмотрим такой пример:

#chunk0
my $aaa = "aaa";

sub chunk1
{
   my $bbb = "bbb";
   return join " ", @_, $aaa, $bbb;
}

for my $i ( 1 .. 10 )
{#chunk2
   for ( 1 .. 10 )
   {#chunk3
      my $ret = chunk1( $i, $_ );
      print "$ret\n";
   }
}

В общем случае чанкой можно назвать любой код, окруженный фигурными скобками.
В примере таких чанок 3 (chunk1, chunk2, chunk3)
+ у нас есть ещё chunk0, границей которого является начало и конец файла.

Упростим всё до чанков:
для получение результата нам нужно выполнить 1 раз chunk0, который состоит из кода(my $aaa = "aaa";) и 10 выполнений chunk2.
chunk2 в свою очередь состоит из 10 выполнений chunk3.
chunk3 состоит из выполнения chunk1 и кода.

Из этой схемы видно, что чанки выполнятся в таком кол-ве:
chunk0 — 1
chunk1 — 100
chunk2 — 10
chunk3 — 100
Что в сумме составит 211 раз.

Далее я пытался описать отличия первого запуска от последующих и понял, что моих знаний не достаточно.
Единственное, что могу сказать точно, что инициализация чанки процесс достаточно ресурсоёмкий, по этому его решили делать 1 раз при первом использовании, а дальше использовать повторно.

Powered by POEM™ Engine Copyright © 2002-2005