Как полностью удалить пакет в Perl?

Как полностью удалить пакет в 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 флаг для прослеживания утечки приводит к полному экрану данных, который я могу опубликовать по запросу.

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

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 находится наш @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

27
задан Eric Strom 27 September 2010 в 19:20
поделиться