Как я могу полностью удалить пакет в Perl? - PullRequest
20 голосов
/ 27 сентября 2010

Как полностью удалить пакет в Perl?Это означает не только переменные пакета, но также любые магические таблицы, которые Perl обновляет для обработки изменений наследования и других вещей.

Этот простой тест:

use warnings; use strict;
use Test::LeakTrace;
use Symbol 'delete_package';

leaktrace {
   package test;
   our $x = 1;

   package main;
   delete_package 'test';
};

приводит к следующему выводу:

leaked ARRAY(0x81c930)  from /lib/perl5/5.10.1/Symbol.pm line 166.
leaked HASH(0x827760)   from /lib/perl5/5.10.1/Symbol.pm line 166.
leaked SCALAR(0x821920) from /lib/perl5/5.10.1/Symbol.pm line 166.

Использование флага -verbose для leaktrace приводит к скринингу данных, которые я могу публиковать по запросу.

Ситуация ухудшается при добавлении строки our @ISA = 'main'; в test пакет:

leaked ARRAY(0x81cd10) from so.pl line 32.
leaked SCALAR(0x81c930) from so.pl line 32.
leaked ARRAY(0x8219d0) from so.pl line 32.
leaked HASH(0x8219c0) from so.pl line 32.
leaked SCALAR(0x8219b0) from so.pl line 32.
leaked HASH(0x8219a0) from so.pl line 32.
leaked SCALAR(0x821970) from /lib/perl5/5.10.1/Symbol.pm line 161.
leaked HASH(0x821950) from so.pl line 32.
leaked SCALAR(0x821940) from so.pl line 32.

В строке 32 находится our @ISA.

Чтобы проиллюстрировать, что это действительно утечки, а не просто шум интерпретатора:

my $num = 0;
while (1) {
    no strict 'refs';
    @{$num.'::ISA'} = 'main';
    delete_package $num++;
}

будет потреблять память с постоянной скоростью

Итак, есть ли лучший способ избавиться от посылки, чем delete_package Symbol?Есть ли что-то еще, что я должен сделать, чтобы помочь ему в этом?

Я видел такое же поведение в 5.8.8, 5.10.1 и 5.12

1 Ответ

5 голосов
/ 30 сентября 2010

Итак, это ошибка в Perl, о которой сообщалось, даже когда вы ее обнаружили.Если не считать исправления, кажется, что единственный способ избежать этих утечек - это выбрать другой подход для решения вашей проблемы.

Почему вам нужен полуанонимный пакет вместо, например, замыкания?Это достаточно просто сделать, чтобы не было утечек, и, проявив некоторую креативность, вы все равно можете реализовать практически все внешние интерфейсы поверх них, например, благословив свои кодовые ссылки замыкания и предоставив им методы, обеспечив их перегрузку и т. Д.1003 *

...