En primer lugar, permítanme decir que sé muy bien cómo funciona VirtualAlloc() y cómo funcionan las instalaciones de memoria virtual de los sistemas operativos modernos, en general.
Dijo que, usando el indicador MAP_RESERVE de la API de Windows VirtualAlloc() , sin usar también MEM_COMMIT , ¿tiene algún uso práctico hoy en día?
Quiero decir, cuando llamo a VirtualAlloc() con MEM_RESERVE|MEM_COMMMIT , reservo y confirmo páginas, pero sé que el sistema operativo realmente asignará páginas solo cuando intente escribir en ellas. Esta optimización ocurre en prácticamente todos los sistemas operativos modernos.
Entonces, con esta optimización en mente, si llamo a VirtualAlloc() con MEM_RESERVE y luego lo llamo varias veces con MEM_COMMIT para confirmar páginas, ¿no es el mismo resultado llamar a VirtualAlloc() solo una vez, especificando MEM_RESERVE|MEM_COMMIT ?
Dado que especificar solo MEM_RESERVE solo reservará direcciones de límite de páginas, sin comprometer páginas reales, pero luego MEM_RESERVE|MEM_COMMIT reservará + confirmará solo las páginas en las que escribo, ¿usar MEM_RESERVE solo no es una pérdida de tiempo hoy? Con solo 1 llamada a VirtualAlloc() con MEM_RESERVE|MEM_COMMIT , básicamente puedo obtener el mismo resultado de llamar a VirtualAlloc() 1 vez con MEM_RESERVE y llamarlo varias N veces con MEM_COMMIT .
Como prueba de lo que digo, he notado que la MEM_RESERVE no existe en absoluto en los sistemas Unices/POSIX que utilizan la llamada al sistema mmap(2) . También allí puede "confirmar" una gran parte de las páginas llamando a mmap(2) una vez, y luego las páginas se asignarán realmente solo cuando escriba en ellas, todo optimizado por el sistema operativo.
Entonces, ¿usar MEM_RESERVE solo es algo útil en los viejos tiempos solo cuando las páginas de memoria eran un recurso valioso, por lo que hoy es inútil? ¿O usar este indicador solo (y luego llamar a VirtualAlloc() N veces con MEM_COMMIT ) todavía tiene algún uso práctico que me falta?
Cuando asigna memoria, el administrador de memoria no le asigna páginas reales de inmediato, perolas cuenta para el número total disponible. El administrador de memoria nunca confirmará más páginas de las que realmente existen, y tiene la garantía de que cuando acceda a una página confirmada, la memoria estará allí.
El propósito de MEM_RESERVE es asignar direcciones de memoria virtual. Puede reservar todo el espacio de direcciones que desee, hasta muchos terabytes en sistemas de 64 bits, incluso si no tiene muchos terabytes de espacio real.
De forma predeterminada, Linux no limita las asignaciones a la cantidad de espacio real disponible. Esta "característica" se llama overcommit . Eso significa que en Linux no hay pasos separados de reserva y confirmación. Si desea reservar espacio de direcciones en Linux, otra pregunta recomienda mmap ping en un área sin permisos. .
Además de la respuesta anterior, aquí hay una cita de los documentos de Microsoft :
Como alternativa a la asignación dinámica, el proceso puede simplemente confirmar toda la región en lugar de solo reservarla. Ambos métodos dan como resultado el mismo uso de memoria física porque las páginas confirmadas no consumen ningún almacenamiento físico hasta que se accede a ellas por primera vez. La ventaja de la asignación dinámica es que minimiza el número total de páginas comprometidas en el sistema. Para asignaciones muy grandes, la confirmación previa de una asignación completa puede hacer que el sistema se quede sin páginas asignables, lo que genera fallas en la asignación de memoria virtual.