我正在对一些非常大的数据进行图形分析,我需要存储一组特定图形边的所有分数。鉴于数据的大小,我需要将信息写入磁盘,并且我正在尝试将绑定哈希与DBM::Deep一起使用。这是基本设置:
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
use autodie;
use File::Spec;
use DBM::Deep;
use Cwd;
my $file = shift;
my $wd = getcwd();
open my $fh, '<', $file;
my %match_pairs;
my $dbm = File::Spec->catfile($wd, "pairs.dbm");
unlink $dbm if -e $dbm;
tie %match_pairs, 'DBM::Deep', {
file => $dbm,
locking => 1,
autoflush => 1,
type => DBM::Deep::TYPE_HASH
};
然后,我解析文件并将信息存储在某个分数阈值之上,如下所示($pair
只是一个常规字符串):
if (exists $match_pairs{$pair}) {
push @{$match_pairs{$pair}}, $score;
}
else {
$match_pairs{$pair} = [$score];
}
此代码会产生内存泄漏,该泄漏会增加,直到您终止该进程。如果我注释掉这六行,就没有内存泄漏。奇怪的是,数据被写入了 DBM 文件,当我使用 DBM::Deep 或不使用时,我得到了相同的结果,所以看起来 tie 方法是正确的。我更改了日志模式、自动刷新、锁定和其他设置,我看到了相同的行为。
我在这里错误地使用 DBM::Deep 吗?例如,我应该使用 OO 接口还是有更好的方法来编写这个方法?
我会先发制人地说,很难提供一个示例文件来重现这个问题,因为脚本需要运行几秒钟才能注意到泄漏(这意味着文件必须至少有 100k 行)。我希望有些东西会跳出来,但如果信息不够,我会提供一个脚本和一些数据。我正在使用 Perl v5.20.2 和最新的 DBM::Deep, 2.0011。
编辑:我已将代码简化为:
$match_pairs{$pair} = $score;
而且我还尝试了 OO 接口做一个简单的键/值存储,我看到了相同的行为。看来这一定是一个错误,所以我会报告它。