para - ¿Cómo manejan las máquinas virtuales modernas la asignación de memoria?
virtual machine descargar (2)
El núcleo de Lua no utiliza malloc
y amigos. Se basa en una función de asignación de memoria suministrada por el usuario que tiene realloc
semántica similar a realloc
(pero es más precisa al tratar los punteros NULL
y los tamaños de 0). Ver lua_Alloc .
La biblioteca auxiliar de Lua proporciona una función conveniente luaL_newstate
que crea un estado Lua a través de la función central lua_newstate
utilizando una función de asignación de memoria basada en realloc
estándar y free
. Otros clientes pueden usar cualquier asignación de memoria que sea adecuada para su aplicación.
Estoy trabajando en una máquina de pila simple escrita en C, principalmente con fines de aprendizaje. Después de usar malloc/free
para mis operaciones de memoria, pensé que sería una buena idea leer un código específico de asignación de memoria de las máquinas virtuales modernas.
Descargué el código fuente de Lua y comencé a leerlo. Después de un tiempo, me di cuenta de que hay muchas cosas de macros involucradas, y no pude encontrar el código donde se realiza la asignación de memoria real (es decir, llamada malloc
).
find . -exec grep -i "malloc" ''{}'' /; -print
Imprimió solo algunas macros Lua que tienen palabra malloc
en sus nombres. ¡El Lua VM (y el lenguaje de programación) no usa malloc
en absoluto!
Así que esto me lleva a la pregunta: ¿cómo manejan las máquinas virtuales modernas la asignación de memoria? ¿Cómo asigna Lua la memoria del montón? ¿Hay alguna otra forma de asignación que no sea malloc
? ¿Cuáles son los pros / contras de otros métodos?
También me pregunto sobre las mejores prácticas, los patrones de diseño, etc. para trabajar de forma segura en la memoria asignada. Veo en la fuente de Lua que hay mucha indirección antes de asignar memoria. ¿Dónde puedo aprender sobre estas cosas?
Lua definitivamente usa malloc
, en forma de realloc
(también se puede pasar un asignador personalizado), sin embargo, debido a que Lua usa un GC como el 99% de los idiomas basados en VM, usa las macros para agregar automáticamente el bloque de encabezado GC al asignación.
Encontrará que la memoria de Lua se maneja con las rutinas LuaM_
en lmem.c
y lmem.h
, todas ellas usan el estado global de la VM para almacenar un asignador, que inicialmente se establece en l_alloc
(de lauxlib.c
), pero puede ser cambiado por lua_setallocf
.
Recientemente, LuaJIT agregó un hundimiento de asignación y planes para algunas funciones de memoria realmente geniales, que puede leer en este artículo sobre la recolección de basura LuaJIT . El artículo cubre una gran cantidad de estrategias y diseños que giran en torno a la asignación de memoria VM / JIT, el hundimiento, la agregación y la recolección de basura.
Como puede ver, la asignación de memoria y las estrategias de hundimiento están estrechamente vinculadas al GC que se emplea (si corresponde).
En términos de ventajas y desventajas de varios asignadores de memoria, usar malloc
estándar es fácil de usar, pero a costa de la velocidad y el desperdicio de alineación y varios bloques adicionales etiquetados en cada asignación.
Al pasar a asignadores de arenas, agrupaciones, bloques y bloques más avanzados, podemos acelerar las cosas drásticamente (especialmente para asignaciones de VM internas de tamaño fijo) y evitar gran parte de la fragmentación y los gastos generales que pueden ocurrir con asignadores más generales como malloc
, pero de Por supuesto, estos asignadores son más complejos, y debe depurarlos si comienza desde cero (lo que en un sistema más grande, como una VM, solo está pidiendo problemas), como corresponde a la probada implementación de malloc
CRT.