Linux: как проверить самый большой непрерывный диапазон адресов, доступный для процесса

Я хочу ввести pid в командной строке и получить самое большое непрерывное адресное пространство, которое не было зарезервировано. Есть идеи?

Наше 32-разрядное приложение, работающее на 64-разрядной версии RHEL 5.4, зависает через некоторое время, скажем, через 24 часа. В то время используется только до 2,5 ГБ памяти, но мы получаем ошибки памяти. Мы думаем, что он не может отображать большие файлы, потому что пространство памяти приложения фрагментировано. Я хотел выйти на рабочие серверы и просто проверить эту теорию.


person johnnycrash    schedule 22.02.2012    source источник
comment
cat /proc/<pid>/maps плюс немного awk/perl/что-то еще?   -  person ninjalj    schedule 23.02.2012
comment
Спасибо! Идеально! Мне пришлось заменить двойное `` на одиночное `, чтобы заставить его работать.   -  person johnnycrash    schedule 23.02.2012


Ответы (3)


Чуть более приятная версия моего комментария выше:

#!perl -T

use warnings;
use strict;

scalar(@ARGV) > 0 or die "Use: $0 <pid>";

my $pid = $ARGV[0];
$pid = oct($pid) if $pid=~/^0/;         # support hex and octal PIDs
$pid += 0; $pid = abs(int($pid));       # make sure we have a number

open(my $maps, "<", "/proc/".$pid."/maps") or
        die "can't open maps file for pid ".$pid;

my $max = 0;
my $end = 0;
while (<$maps>) {
        /([0-9a-f]+)-([0-9a-f]+)/;
        $max = hex ($1) - $end if $max < hex ($1) - $end;
        $end = hex ($2);
}

close ($maps);

END {
        print "$max\n";
}
person ninjalj    schedule 22.02.2012
comment
Действительно ли #!perl работает? У меня сложилось впечатление, что всегда должен быть абсолютный путь. - person zwol; 23.02.2012
comment
@Зак: не совсем так. Я поместил его туда только для того, чтобы заставить -T (это просто показывает, что я сделал слишком много код-гольфа). - person ninjalj; 23.02.2012
comment
Небольшая придирка — вы забыли проверить пространство после окончания последнего сопоставления (которое заканчивается на максимально допустимом адресе пользовательского пространства, что зависит от конфигурации ядра). - person caf; 23.02.2012

Вероятно, это не совсем то, что вам нужно, но внутри процесса можно выполнять двоичный поиск с помощью mmaping без выделения памяти. т.е. mmap(4GB), если не получится mmap(2GB), если получится mmap(3GB) и так далее.

person Maxim Egorushkin    schedule 22.02.2012

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

Тем не менее, можно также получить ошибки OOM, имея на бумаге много свободных диапазонов виртуальных адресов, например, из-за недостаточного количества оперативной памяти + подкачки. Кроме того, в вашей системе и/или программе (программах) может быть отключена перегрузка (sysctl -a) или заблокирована подкачка (mlock (2)), или у вас на самом деле есть очень резкое ограничение на сопоставления (ulimit -v) — последнее легко запустить, учитывая, что некоторые дистрибутивы так или иначе устанавливают такие ulimits.

person jørgensen    schedule 22.02.2012
comment
У нас есть более 70 ГБ на каждом сервере. Мы запускаем 24 копии приложения. Он достигает примерно 2,5 г, а затем исчезает без основного файла. Я собираюсь сделать запись в журнале, возможно, она уже есть, когда не удается выполнить malloc или mmap. Каждый сервер использует около 1 г общей памяти mmap. ulimit -v неограниченная избыточная_память = 0 - person johnnycrash; 23.02.2012