我有一个Perl脚本,我使用哈希表维护一个非常简单的缓存。一旦占用超过n个字节,我想清除哈希值,以避免Perl(32位)耗尽内存并崩溃。

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

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

但是有可能检查哈希所占用的实际内存吗?

有帮助吗?

解决方案

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

但是, Cache :: SizeAwareMemoryCache Tie :: Cache 已经实现了你正在寻找的东西(有些不同的界面),并且可以帮你避免重新发明轮。

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

其他提示

您正在寻找 Devel :: Size

NAME

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);

您可以安装 Devel :: Size 以查找所占用的内存Perl中的任何构造。但请注意,它将需要大量的中间内存,因此我不会将它用于大型数据结构。如果你认为你可能会失去记忆,我肯定不会这样做。

顺便说一下,CPAN上有很多好的模块可以在内存和其他方面进行缓存。而不是自己滚动我会建议使用其中之一。例如,尝试 Tie :: Cache :: LRU 内存缓存只能达到指定数量的密钥。

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

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

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

缓存::内存

use Cache::Memory;

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

my $size  = $cache->size()
my $limit = $cache->size_limit();

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

Cache :: SizeAwareMemoryCache 可以告诉您希望它的最大尺寸使用,然后你可以留下来关心你的缓存。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top