Как полностью удалить пакет в 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