我在Perl中遇到了一些内存问题。当我填充一个大的哈希表时,无法将内存释放回操作系统。如果我用标量做同样的操作并使用undef
,则它会将内存还给操作系统。
以下是我编写的测试程序。
#!/usr/bin/perl
###### Memory test
######
## Use Commands
use Number::Bytes::Human qw(format_bytes);
use Data::Dumper;
use Devel::Size qw(size total_size);
## Create Varable
my $share_var;
my %share_hash;
my $type_hash = 1;
my $type_scalar = 1;
## Start Main Loop
while (true) {
&Memory_Check();
print "Hit Enter (add to memory): "; <>;
&Up_Mem(100_000);
&Memory_Check();
print "Hit Enter (Set Varable to nothing): "; <>;
$share_var = "";
$share_hash = ();
&Memory_Check();
print "Hit Enter (clean data): "; <>;
&Clean_Data();
&Memory_Check();
print "Hit Enter (start over): "; <>;
}
exit;
#### Up Memory
sub Up_Mem {
my $total_loops = shift;
my $n = 1;
print "Adding data to shared varable $total_loops times\n";
until ($n > $total_loops) {
if ($type_hash) {
$share_hash{$n} = 'X' x 1111;
}
if ($type_scalar) {
$share_var .= 'X' x 1111;
}
$n += 1;
}
print "Done Adding Data\n";
}
#### Clean up Data
sub Clean_Data {
print "Clean Up Data\n";
if ($type_hash) {
## Method to fix hash (Trying Everything i can think of!
my $n = 1;
my $total_loops = 100_000;
until ($n > $total_loops) {
undef $share_hash{$n};
$n += 1;
}
%share_hash = ();
$share_hash = ();
undef $share_hash;
undef %share_hash;
}
if ($type_scalar) {
undef $share_var;
}
}
#### Check Memory Usage
sub Memory_Check {
## Get current memory from shell
my @mem = `ps aux | grep \"$$\"`;
my($results) = grep !/grep/, @mem;
## Parse Data from Shell
chomp $results;
$results =~ s/^\w*\s*\d*\s*\d*\.\d*\s*\d*\.\d*\s*//g; $results =~ s/pts.*//g;
my ($vsz,$rss) = split(/\s+/,$results);
## Format Numbers to Human Readable
my $h = Number::Bytes::Human->new();
my $virt = $h->format($vsz);
my $h = Number::Bytes::Human->new();
my $res = $h->format($rss);
print "Current Memory Usage: Virt: $virt RES: $res\n";
if ($type_hash) {
my $total_size = total_size(\%share_hash);
my @arr_c = keys %share_hash;
print "Length of Hash: " . ($#arr_c + 1) . " Hash Mem Total Size: $total_size\n";
}
if ($type_scalar) {
my $total_size = total_size($share_var);
print "Length of Scalar: " . length($share_var) . " Scalar Mem Total Size: $total_size\n";
}
}
输出:
./Memory_Undef_Simple.cgi 当前内存使用情况:虚拟内存:6.9K 实际内存:2.7K 哈希长度:0 哈希内存总大小:92 标量长度:0 标量内存总大小:12 按 Enter 键(添加到内存): 向共享变量添加数据 100000 次 完成添加数据 当前内存使用情况:虚拟内存:228K 实际内存:224K 哈希长度:100000 哈希内存总大小:116813243 标量长度:111100000 标量内存总大小:111100028 按 Enter 键(将变量设置为空): 当前内存使用情况:虚拟内存:228K 实际内存:224K 哈希长度:100000 哈希内存总大小:116813243 标量长度:0 标量内存总大小:111100028 按 Enter 键(清除数据): 清除数据 当前内存使用情况:虚拟内存:139K 实际内存:135K 哈希长度:0 哈希内存总大小:92 标量长度:0 标量内存总大小:24 按 Enter 键(重新开始):
你可以看到内存下降了,但它只降低了标量的大小。有什么办法可以释放哈希表的内存吗?
此外,Devel::Size
显示哈希表只使用了 92 字节,尽管程序仍在使用 139K。