我有一个Perl脚本,我使用哈希表维护一个非常简单的缓存。一旦占用超过n个字节,我想清除散列,以避免Perl(32位)耗尽内存并崩溃。
我可以检查键值对的数量:
if (scalar keys %cache > $maxSize)
{
%cache = ();
}
但是有可能检查哈希所占用的实际内存吗?
答案 0 :(得分:27)
Devel::Size是您问题的答案。 (请注意,Devel :: Size在处理大型数据结构时会暂时分配大量内存,因此它不太适合此目的。)
但是,Cache::SizeAwareMemoryCache和Tie::Cache已经实现了您正在寻找的东西(界面略有不同),并且可以帮助您避免重新发明轮子。
Memoize是一个模块,可以很容易地缓存函数的返回值。它没有实现基于大小的缓存限制,但应该可以使用Tie :: Cache作为Memoize的后端。
答案 1 :(得分:11)
您正在寻找Devel::Size
Devel :: Size - 用于查找Perl变量的内存使用情况的Perl扩展
use Devel::Size qw(size total_size);
my $size = size("A string");
my @foo = (1, 2, 3, 4, 5);
my $other_size = size(\@foo);
my $foo = {a => [1, 2, 3],
b => {a => [1, 3, 4]}
};
my $total_size = total_size($foo);
答案 2 :(得分:5)
您可以安装Devel::Size以查找Perl中任何构造所占用的内存。但请注意,它将需要大量的中间内存,因此我不会将它用于大型数据结构。如果你认为你可能会失去记忆,我肯定不会这样做。
顺便说一下,CPAN上有很多好的模块可以在内存和其他方面进行缓存。而不是自己滚动我会建议使用其中之一。例如,尝试Tie::Cache::LRU获取内存缓存,该缓存只能达到指定数量的密钥。
答案 3 :(得分:2)
您可以使用Devel::Size来确定使用的内存,但通常无法为操作系统提供返回内存。听起来你只是试图清理和重用,这应该可以正常工作。
如果缓存是针对某个功能的,请考虑使用Memoize模块而不是自己维护缓存。它支持缓存过期(通过Memoize :: Expire),因此您可以限制缓存的大小而不会完全破坏缓存。
答案 4 :(得分:1)
use Cache::Memory;
my $cache = Cache::Memory->new(
namespace => 'MyNamespace',
default_expires => '600 sec'
);
my $size = $cache->size()
my $limit = $cache->size_limit();
答案 5 :(得分:1)
如果您担心管理Perl正在使用的内存量,您应该考虑另一种方法。为什么你一次需要RAM很多?你应该使用某种持久性系统吗?
答案 6 :(得分:0)
正如其他人所说,缓存不是你需要重新发明的轮子,CPAN上有很多简单的缓存解决方案,可以很好地为你做好工作。
Cache::SizeAwareMemoryCache可以告诉您希望它使用的最大大小,然后您可以将它留给您关注缓存。