18

我有一个 Perl 脚本,我在其中使用哈希表维护一个非常简单的缓存。一旦它占用超过 n 个字节,我想清除哈希,以避免 Perl(32 位)内存不足和崩溃。

我可以检查键值对的数量:

if (scalar keys %cache > $maxSize)
 {
 %cache = ();
 }

但是是否可以检查散列占用的实际内存?

4

7 回答 7

27

Devel::Size是您问题的答案。(请注意,Devel::Size 在处理大型数据结构时会临时分配大量内存,因此它不太适合此目的。)

但是,Cache::SizeAwareMemoryCacheTie::Cache已经实现了您正在寻找的东西(使用有些不同的接口),并且可以避免您重新发明轮子。

Memoize是一个模块,可以轻松缓存函数的返回值。它没有实现基于大小的缓存限制,但应该可以使用 Tie::Cache 作为 Memoize 的后端。

于 2008-09-20T01:00:18.163 回答
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);
于 2008-09-20T00:32:22.630 回答
6

您可以安装Devel::Size以找出 Perl 中任何构造所占用的内存。但是请注意,它会占用大量中间内存,因此我不会将它用于大型数据结构。如果您认为您可能即将耗尽内存,我当然不会这样做。

顺便说一句,CPAN 上有许多很好的模块可以在内存中进行缓存等。我建议不要自己动手,而是使用其中之一。例如,尝试Tie::Cache::LRU用于内存缓存,该缓存只能达到指定数量的键。

于 2008-09-20T00:39:40.990 回答
2

您可以使用Devel::Size来确定使用的内存,但通常不能将返回内存提供给操作系统。不过,听起来您只是想清除和重用,这应该可以正常工作。

如果缓存是用于函数的,请考虑使用Memoize模块,而不是自己维护缓存。它支持缓存过期(通过 Memoize::Expire),因此您可以限制缓存的大小而不会完全破坏它。

于 2008-09-20T00:39:28.650 回答
1

高速缓存存储器

use Cache::Memory;

my $cache = Cache::Memory->new(
  namespace => 'MyNamespace',
  default_expires => '600 sec'
);

my $size  = $cache->size()
my $limit = $cache->size_limit();
于 2008-09-20T01:31:12.753 回答
1

如果您担心管理 Perl 正在使用的内存量,您可能应该考虑另一种方法。为什么你一次需要这么多内存?你应该使用某种持久性系统吗?

于 2008-09-22T00:53:38.973 回答
0

正如其他人所说,缓存不是您需要重新发明的轮子,CPAN 上有很多简单的缓存解决方案可以很好地为您完成这项工作。

Cache::SizeAwareMemoryCache可以被告知您希望它使用的最大大小,然后您可以让它为您处理缓存。

于 2008-12-08T16:38:28.597 回答