Как найти количество физической памяти, занятой хешем в Perl?
У меня есть Perl script, где я поддерживаю очень простой кеш, используя хеш-таблицу. Я хотел бы очистить хэш, если он занимает больше, чем n байтов, чтобы избежать переполнения памяти (32-разрядной версии) и сбоя памяти.
Я могу проверить количество пар ключей-значений:
if (scalar keys %cache > $maxSize)
{
%cache = ();
}
Но можно ли проверить фактическую память, занятую хешем?
Ответы
Ответ 1
Devel::Size - ответ на ваш вопрос. (Обратите внимание, что Devel:: Size временно выделяет значительный объем памяти при обработке большой структуры данных, поэтому он не очень хорошо подходит для этой цели.)
Однако Cache::SizeAwareMemoryCache и Tie::Cache уже реализуют то, что вы ищете (с несколькими разными интерфейсами), и можете спасти вас от переосмысления колеса.
Memoize - это модуль, который упрощает кэширование возвращаемого значения из функции. Он не реализует ограничение на кеширование на основе размера, но должно быть возможно использовать Tie:: Cache в качестве backend для Memoize.
Ответ 2
Вы ищете 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);
Ответ 3
Вы можете установить Devel::Size, чтобы узнать память, полученную любой конструкцией в Perl. Однако имейте в виду, что для этого потребуется большая промежуточная память, поэтому я бы не использовал ее против большой структуры данных. Я бы, конечно, не сделал этого, если вы думаете, что у вас может быть нехватка памяти.
Кстати, в CPAN есть несколько хороших модулей для кэширования в памяти и в противном случае. Вместо того, чтобы катиться самостоятельно, я бы предложил использовать один из них. Например, попробуйте Tie::Cache::LRU для кеша в памяти, который будет идти только до указанного количества ключей.
Ответ 4
Вы можете использовать Devel::Size, чтобы определить используемую память, но обычно вы не можете вернуть оперативную память. Похоже, вы просто пытаетесь очистить и повторно использовать, хотя это должно работать нормально.
Если кеш предназначен для функции, рассмотрите возможность использования модуля Memoize, а не для сохранения кеша. Он поддерживает кеширование (через Memoize:: Expire), поэтому вы можете ограничить размер кеша, не уничтожая его полностью.
Ответ 5
use Cache::Memory;
my $cache = Cache::Memory->new(
namespace => 'MyNamespace',
default_expires => '600 sec'
);
my $size = $cache->size()
my $limit = $cache->size_limit();
Ответ 6
Если вы беспокоитесь об управлении объемом памяти, используемой Perl, вероятно, вам стоит взглянуть на альтернативный подход. Зачем вам нужно столько всего в ОЗУ сразу? Если вы используете какую-то систему настойчивости?
Ответ 7
Как говорили другие, кеширование - это не колесо, которое вам нужно заново изобретать, есть много простых решений кэширования на CPAN, которые прекрасно справятся с работой.
Cache::SizeAwareMemoryCache можно указать максимальный размер, который вы хотите использовать, тогда вы можете оставить его для ухода за кешем для вас.