Что могло вызывать повтор mmap / munmap в результатах strace?

У меня есть приложение (node.js), которое иногда вызывает 100 % Использование процессора. Я подключился к процессу с помощью strace , когда он был в этом состоянии, но я не знаю, что делать, если strace выводит. Результаты повторяются для этих двух шаблонов (сокращено):

mmap(0x30c3ac700000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x30c3ac700000
mmap(0x3364514ba000, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x3364514ba000
munmap(0x3364514ba000, 286720)          = 0
munmap(0x336451600000, 761856)          = 0
mmap(0x336451500000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x336451500000
mmap(0x2b9c33880000, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x2b9c33880000
munmap(0x2b9c33880000, 524288)          = 0
munmap(0x2b9c33a00000, 524288)          = 0
...

И ...

munmap(0x2b9c33900000, 1048576)         = 0
munmap(0x336451500000, 1048576)         = 0
munmap(0x30c3ac700000, 1048576)         = 0
munmap(0x247e37500000, 1048576)         = 0
munmap(0x20d76c800000, 1048576)         = 0
munmap(0x1cae0d600000, 1048576)         = 0
munmap(0x163545100000, 1048576)         = 0
munmap(0x32dcfe700000, 1048576)         = 0
munmap(0x1a1feff00000, 1048576)         = 0
munmap(0x3fb72f00000, 1048576)          = 0
munmap(0x366536900000, 1048576)         = 0
...

Может ли кто-нибудь пролить свет на то, что здесь может происходить? Спасибо!

2
задан 16 April 2017 в 20:32
1 ответ

Все, что можно вывести из этих выходных данных, - это то, что приложение выделяет и освобождает память. Поэтому должны быть некоторые структуры данных, которые растут и сжимаются.

Это, к сожалению, мало что говорит о том, что происходит на более высоком уровне приложения.

Мы также можем сделать некоторые выводы о том, как реализация управления памятью в node.js реализовано, поскольку существует два разных варианта аргументов для mmap .

PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE

Эти аргументы выделяют адресное пространство, но PROT_NONE означает зарезервированный адрес пространство не может быть использовано (если другой вызов не сделает его доступным).

PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS

Эти аргументы выделяют фактическую память для определенного диапазона адресов (который предположительно ранее был выделен с другой комбинацией аргументов) и превращает ее в чтение / запись регион.

Почему это происходит, мы можем догадаться, посмотрев на эту последовательность из четырех системных вызовов:

mmap(0x3364514ba000, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x3364514ba000
munmap(0x3364514ba000, 286720)          = 0
munmap(0x336451600000, 761856)          = 0
mmap(0x336451500000, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x336451500000

Это выделяет 2 МБ адресного пространства. Затем освободите начало и конец этого адресного пространства и, наконец, выделите 1 МБ памяти для средней части выделенного адресного пространства.

Фактически, эти четыре вызова выделяют 1 МБ памяти с адресом, выровненным с кратностью 1 МБ. Итак, мы рассматриваем шаблон, который явно хочет выровнять адреса.

Последующие вызовы munmap просто освобождают блоки размером 1 МБ, выделенные ранее. В частности, я заметил

munmap(0x336451500000, 1048576)         = 0

, что освобождает блок размером 1 МБ, выделенный в приведенных выше четырех системных вызовах.

Вероятно, все это не то, что вы хотели знать. Но, к сожалению, именно это можно вывести из вывода strace , так что вам придется искать другие способы найти информацию, которую вы действительно хотите знать.

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

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

3
ответ дан 3 December 2019 в 10:35

Теги

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