Подтвердить что ты не робот

Как современные виртуальные машины обрабатывают выделение памяти?

Я работаю над простой стековой машиной, написанной на C, в основном для обучения. После использования malloc/free для операций с памятью я подумал, что было бы неплохо прочитать некоторый код выделения памяти из современных виртуальных машин.

Я загрузил исходный код Lua и начал его читать. Через некоторое время я понял, что есть много макросов, и я не смог найти код, в котором выполняется реальное выделение памяти (т.е. Вызов malloc).

find . -exec grep -i "malloc" '{}' \; -print

Он печатал только некоторые макросы Lua, которые имеют malloc слово в своих именах. Lua VM (и язык программирования) вообще не использует malloc!

Итак, это приводит меня к вопросу: как современные виртуальные машины обрабатывают выделение памяти? Как Lua выделяет память из кучи? Существуют ли какие-либо способы выделения, кроме malloc? Каковы плюсы и минусы других методов?

Мне также интересно узнать о лучших практиках, шаблонах проектирования и т.д. для безопасной работы с выделенной памятью. Я вижу в источнике Lua, что перед распределением памяти существует много косвенных ограничений. Где я могу узнать об этом?

4b9b3361

Ответ 1

Lua наиболее определенно использует malloc в форме realloc (также можно также передать настраиваемый распределитель), поскольку Lua использует GC как 99% языков на основе VM, он автоматически использует макросы добавьте блок заголовка GC в выделение.

Вы найдете всю память Lua, обрабатываемую подпрограммами LuaM_ в lmem.c и lmem.h, все они используют глобальное состояние виртуальной машины для хранения распределителя, изначально установленного на l_alloc (from lauxlib.c), но его можно изменить на lua_setallocf.

Недавно LuaJIT добавила потоки выделения и планирует некоторые действительно интересные функции памяти, которые вы можете прочитать в этой статье на LuaJIT Garbage Collection, В статье рассмотрены многие стратегии и разработки, связанные с распределением памяти VM/JIT, потоками, агрегацией и сбором мусора.

Как вы можете видеть, стратегии распределения памяти и снижения уровня очень тесно связаны с используемым GC (если есть).

В терминах pro и con различных распределителей памяти использование стандартного malloc прост в использовании, но за счет скорости и потерь для выравнивания и различных дополнительных блоков, помеченных для каждого распределения.

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

Ответ 2

Ядро Lua не использует malloc и друзей. Он полагается на предоставленную пользователем функцию распределения памяти, которая имеет realloc -подобную семантику (но точнее при обработке указателей NULL и размеров 0). См. lua_Alloc.

Вспомогательная библиотека Lua предоставляет удобную функцию luaL_newstate, которая создает состояние Lua через основную функцию lua_newstate, используя функцию выделения памяти на основе стандартных realloc и free. Другие клиенты могут использовать любое распределение памяти, подходящее для своего приложения.