185 похожих чатов

Пару слов об аллокаторах, раз уж я в тележку залез.

:)

Еще пару лет назад я считал, что выделение памяти приложению происходит так, как описано во всех букварях — приложение вызывает malloc() и через него запрашивает у оси нужное кол-во памяти. Потом в нужный момент возвращает через free() (вроде так функция называется). В этой простой схеме malloc — лишь "посредник", мальчик-падаван, ходит в ось за памятью и приносит ее приложению, ну и обратно отдает тоже.

Оказалось, что пытливые умы разработчиков осей уже давным-давно эту схему усложнили — malloc теперь является не просто подаваном, он не хочет больше быть на побегушках. Он организовал свой собственный департамент распоряжения памятью :) и, хоть по-прежнему ходит в ось, получая память, практически перестал ходить в ось, чтобы ее отдать. Он ее себе в заначку складывает ("и вот на эти два прОцента я и живу" (C)). И когда приложению снова нужна память, malloc отдает ее из своих запасов, не обращаясь к оси (если у него конечно есть нужный объем).

Так вот алгоритмы распоряжения этой заначкой — это тот краегоульный камень, об который бьются разработчики сторонних аллокаторов, каждый реализует свои собственные. Там есть масса моментов, которые можно оптимизировать, в частности, фрагментация памяти. Почти как с фрагментацией файлов на диске, проблемы те же. И если у аллокатора в заначке есть, скажем, 1GB памяти, но кусками по 100MB, а приложение запросило 500MB разом, т.е. одним непрерывным куском, то аллокатор говорит "у меня столько нету" и идет в ось попрошайничать. А тот суммарный гиг, что у него порезанный в заначке лежит — он так и лежит. И при неудачном стечении обстоятельств может лежать долго. А при еще более неудачном — может плодиться и размножаться.

Проблема в том, что аллокатор работает в адресном пространстве процесса, который память запрашивает. В нашем случае — вапора. Т.е. вся память, которую аллокатор получил у оси (и та, что он приложению отдал, и та, что в заначке лежит) — она считается выделенной процессу!

Т.е. если другими словами сказать, то в рамках выполняемого нашего процесса (вапор) сидит присосавшийся к нему спекулянт памятью и мутит свои делишки. С точки зрения оси, он — часть нашего процесса. С точки зрения процесса, он — часть оси.

Вроде 50/50, если по-справедливости, но когда и что в нашем мире бывает по-справедливости? В нашем случае рулит не справедливость, а главенство — и ось тут главная. Она видит 8 гигов памяти, которые она выделила процессу (при этом 7 из них лежат в заначке у аллокатора, мелко покрошенные, а сам вапор использует 1 гиг) и говорит — а не охренел ли ты, дружок? И насылает на процесс ООМ-киллера.

Дальше всё хорошо — рестарт, обнуление, очередной "зубец" на графиках потребления памяти.

Так и живем.

Отсюда становится понятным, что качество алгоритмов аллокатора, управляющего нашей памятью (т.е. памятью, которая была осью выделена нашему процессу) напрямую влияет на наш процесс, ничуть не меньше, чем качество того кода, который мы сами написали.

И как следствие — есть прямой интерес выбрать и использовать хороший аллокатор. Оси от этого ни холодно, ни жарко, это влияет только на нас, ей плевать, а вот нам не плевать, это же наш процесс будет крашиться.

Получается, что раз нельзя отказаться от этого присосавшегося спекулянта (таковы правила игры в современных осях), то можно и нужно хотя бы заменить его на более лучший. Тем более, что делается это легко и просто, и есть, из чего выбрать.

3 ответов

128 просмотров

к вопросу про jemalloc, и про ненавистный Docker!) в шаблоне Vapor он с этого начинает билдить среду для выполнения...

Alex-Sherbakov Автор вопроса
Egor Ledkov
screenshot к вопросу про jemalloc, и про ненавистный Docker!)...

Ну вот в Debian 12 выбрали дефолтным почему-то не jemalloc, а mimalloc, так что я после апгрэйда системы jemalloc для вапора отключил, посмотрим, как оно будет. Про mimalloc отзывы и до этого были хорошие. Есть еще гугловский, tmalloc или как-то так, не помню точное название.

Alex Sherbakov
Ну вот в Debian 12 выбрали дефолтным почему-то не ...

вот этот образ swift собран на базе ubuntu. Не знаю какой там дефолтный..

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

Обсуждают сегодня

30500 за редактор? )
Владимир
47
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Он в одиночку это дело запилил или была какая-то команда?
Aquinary
12
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Oh sorry did you want it in Gunter's chains?
Martin Rys
15
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Подскажите пожалуйста, как в CustomDrawCell(Sender: TcxCustomGridTableView; ACanvas: TcxCanvas; AViewInfo: TcxGridTableDataCellViewInfo; var ADone: Boolean); получить наз...
A Z
7
Раз начали говорить про embassy, то присоединюсь со своими парой вопросов. 1) Есть ли сопоставимые аналоги для асинхронного кода в emdebbed? 2) Можно ли внутри задач embassy ...
NI_isx
6
Карта сайта