Вопрос по hash, perl, memory – Как найти объем физической памяти, занимаемый хешем в Perl?

17

У меня есть сценарий Perl, где я поддерживаю очень простой кеш, используя хэш-таблицу. Я хотел бы очистить хеш, если он занимает более n байтов, чтобы избежать исчерпания памяти и сбоя Perl (32-бит).

Я могу проверить количество пар ключ-значение:

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

Но возможно ли проверить фактическую память, занятую хешем?

Ваш Ответ

7   ответов
27

Devel :: Размер это ответ на ваш вопрос. (Обратите внимание, что Devel :: Size будет временно выделять значительный объем памяти при обработке большой структуры данных, поэтому он не очень подходит для этой цели.)

Тем не мение,Cache :: SizeAwareMemoryCache а такжеTie :: Cache уже реализовать то, что вы ищете (с несколько другими интерфейсами), и может спасти вас от повторного изобретения колеса.

Memoize это модуль, который упрощает кеширование возвращаемого значения из функции. Он не реализует ограничение размера кэша на основе размера, но должна быть возможность использовать Tie :: Cache в качестве бэкэнда для Memoize.

5

Devel :: Размер чтобы узнать память, занятую любой конструкцией в Perl. Однако имейте в виду, что это займет большой объем промежуточной памяти, поэтому я не буду использовать ее для большой структуры данных. Я бы не стал этого делать, если вы думаете, что у вас может закончиться память.

Кстати, в CPAN есть несколько хороших модулей для кэширования в памяти и в других случаях. Вместо того, чтобы бросать свои собственные, я бы предложил использовать один из них. Например попробуйтеTie :: Cache :: LRU для кэша в памяти, который будет идти только до указанного количества ключей.

1
Cache::Memory
use Cache::Memory;

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

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

кеширование - это не то колесо, которое нужно заново изобретать, есть множество простых решений для кеширования на CPAN, которые хорошо вам подойдут.

Cache :: SizeAwareMemoryCache можно указать максимальный размер, который вы хотите использовать, затем вы можете оставить его, чтобы заботиться о кеше для вас.

11

Devel :: Размер

NAME

Devel :: Size - расширение Perl для поиска использования памяти переменных Perl

SYNOPSIS
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);
@ Iv & # xE1; nRodr & # xED; guezTorres, если вы не используете bignums, большие числа сохраняются как значения с плавающей запятой двойной точности, которые имеют одинаковый размер.
почему при использовании в скалярах 5, 6 или даже 60000000000000000000000000000000000000 я всегда получаю один и тот же результат? Я ожидаю, что выше 2 ^ 63 -1 скаляры занимают больше байтов, чем просто 24, что является суммой, которую я получаю @cjm
Вы должны были предупредить спрашивающего, что при использовании Devel :: Size в большой структуре данных будет использоваться очень большой объем памяти.
1

который использует Perl, вам, вероятно, следует рассмотреть альтернативный подход. Зачем вам столько памяти одновременно? Должны ли вы использовать какую-то систему персистентности?

2

Devel :: Размер для определения используемой памяти, но вы, как правило, не можете возвращать память операционной системе. Похоже, вы просто пытаетесь очистить и использовать повторно, что должно работать нормально.

Если кэш предназначен для функции, рассмотрите возможность использованияMemoize модуль вместо поддержания кеша самостоятельно. Он поддерживает срок действия кэша (через Memoize :: Expire), так что вы можете ограничить размер кэша, не разрушая его полностью.

Похожие вопросы