У меня есть серверный процесс, реализованный в haskell, который действует как простой двоичный файл in-memory. Клиентские процессы могут подключаться, а затем добавлять и извлекать данные. Служба использует больше памяти, чем я ожидал бы, и я пытаюсь понять, почему.
Самая грубая метрика у меня есть linux "top". Когда я запускаю процесс, я вижу размер изображения "VIRT" размером ~ 27 МБ. После запуска клиента для вставки 60 000 элементов данных я вижу размер изображения ~ 124 МБ.
Запуск процесса для сбора статистики GC (+ RTS -S), я вижу первоначально
Alloc Copied Live GC GC TOT TOT Page Flts
bytes bytes bytes user elap user elap
28296 8388 9172 0.00 0.00 0.00 0.32 0 0 (Gen: 1)
и при добавлении элементов 60k я вижу, что живые байты плавно растут до
...
532940 14964 63672180 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
532316 7704 63668672 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
530512 9648 63677028 0.00 0.00 23.50 31.95 0 0 (Gen: 0)
531936 10796 63686488 0.00 0.00 23.51 31.96 0 0 (Gen: 0)
423260 10047016 63680532 0.03 0.03 23.53 31.99 0 0 (Gen: 1)
531864 6996 63693396 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531852 9160 63703536 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531888 9572 63711876 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531928 9716 63720128 0.00 0.00 23.55 32.01 0 0 (Gen: 0)
531856 9640 63728052 0.00 0.00 23.55 32.02 0 0 (Gen: 0)
529632 9280 63735824 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
527948 8304 63742524 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
528248 7152 63749180 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
528240 6384 63756176 0.00 0.00 23.56 32.02 0 0 (Gen: 0)
341100 10050336 63731152 0.03 0.03 23.58 32.35 0 0 (Gen: 1)
5080 10049728 63705868 0.03 0.03 23.61 32.70 0 0 (Gen: 1)
Кажется, это говорит мне, что куча имеет ~ 63 МБ живых данных. Это может быть совместимо с числами сверху, к тому времени, когда вы добавляете в пространство стека, кодовое пространство, накладные расходы GC и т.д.
Итак, я попытался использовать профилировщик кучи, чтобы выяснить, что составляет это 63 МБ. Результаты сбивают с толку. Запуск с помощью "+ RTS -h" и просмотр сгенерированный hp файл, последний и самый большой моментальный снимок имеет:
containers-0.3.0.0:Data.Map.Bin 1820400
bytestring-0.9.1.7:Data.ByteString.Internal.PS 1336160
main:KV.Store.Memory.KeyTree 831972
main:KV.Types.KF_1 750328
base:GHC.ForeignPtr.PlainPtr 534464
base:Data.Maybe.Just 494832
THUNK 587140
Все остальные числа в снимке намного меньше этого. Добавление этих значений дает пиковое использование памяти как ~ 6 МБ, что отражено в вывод графика:
Почему это не соответствует живым байтам, как показано в статистике GC? Это трудно понять, как мои структуры данных могут потребовать 63 МБ, и профайлер говорит, что это не так. Где память идет?
Спасибо за любые советы или указатели на это.
Тим