¿Cómo el sistema operativo limita el tamaño de la pila y el montón?


21

Nota : si necesita considerar un sistema operativo específico para poder responder, considere Linux.

Cada vez que ejecuto un programa, se le dará un espacio de memoria virtual para ejecutar, con un área para su pila y otra para su montón.

Pregunta 1 : ¿la pila y el montón tienen un límite de tamaño estático (por ejemplo, 2 gigabytes cada uno), o es este límite dinámico, que cambia de acuerdo con las asignaciones de memoria durante la ejecución del programa (es decir, 4 gigabytes en total para ser utilizados por ambos, entonces si un programa solo usa la pila, ¿podrá tener una pila con 4 gigabytes?

Pregunta 2 : ¿Cómo se define el límite? ¿Es la memoria RAM total disponible?

Pregunta 3 : ¿Qué pasa con el texto (código) y las secciones de datos, cómo están limitados?


Respuestas:


23

Hay dos límites de memoria diferentes. El límite de memoria virtual y el límite de memoria física.

Memoria virtual

La memoria virtual está limitada por el tamaño y el diseño del espacio de direcciones disponible. Por lo general, al principio es el código ejecutable y los datos estáticos y pasados ​​que crecen el montón, mientras que al final es el área reservada por el núcleo, antes que las bibliotecas compartidas y la pila (que en la mayoría de las plataformas disminuye). Eso le da al montón y a la pila espacio libre para crecer, las otras áreas se conocen y se reparan al inicio del proceso.

La memoria virtual libre no se marca inicialmente como utilizable, pero se marca como tal durante la asignación. Si bien el almacenamiento dinámico puede crecer a toda la memoria disponible, la mayoría de los sistemas no crecen automáticamente las pilas. El límite predeterminado de IIRC para la pila es 8MiB en Linux y 1MiB en Windows y se puede cambiar en ambos sistemas. La memoria virtual también contiene cualquier archivo y hardware mapeados en memoria.

Una razón por la cual la pila no puede crecer automáticamente (arbitrariamente) es que los programas multiproceso necesitan una pila separada para cada subproceso, por lo que eventualmente se interpondrán en el camino del otro.

En las plataformas de 32 bits, la cantidad total de memoria virtual es de 4 GiB, tanto Linux como Windows normalmente reservan los últimos 1 GiB para el núcleo, lo que le brinda un máximo de 3 GB de espacio de direcciones. Hay una versión especial de Linux que no reserva nada que le brinde 4GiB completos. Es útil para el raro caso de grandes bases de datos donde el último 1GiB ahorra el día, pero para el uso regular es un poco más lento debido a las recargas adicionales de la tabla de páginas.

En las plataformas de 64 bits, la memoria virtual es 64EiB y no tiene que pensarlo.

Memoria física

La memoria física generalmente solo es asignada por el sistema operativo cuando el proceso necesita acceder a ella. La cantidad de memoria física que utiliza un proceso es un número muy difuso, ya que parte de la memoria se comparte entre procesos (el código, las bibliotecas compartidas y cualquier otro archivo asignado), los datos de los archivos se cargan en la memoria a pedido y se descartan cuando hay escasez de memoria y La memoria "anónima" (la que no está respaldada por archivos) puede intercambiarse.

En Linux, lo que sucede cuando se queda sin memoria física depende de la vm.overcommit_memoryconfiguración del sistema. El valor predeterminado es comprometerse de más. Cuando le pide al sistema que asigne memoria, le da algo, pero solo asigna la memoria virtual. Cuando realmente acceda a la memoria, intentará obtener algo de memoria física para usar, descartando datos que se puedan releer o intercambiando cosas según sea necesario. Si descubre que no puede liberar nada, simplemente eliminará el proceso de la existencia (no hay forma de reaccionar, porque esa reacción podría requerir más memoria y eso conduciría a un bucle sin fin).

Así es como mueren los procesos en Android (que también es Linux). La lógica se mejoró con la lógica de qué proceso eliminar de la existencia en función de lo que está haciendo el proceso y la antigüedad que tiene. Los procesos de Android simplemente dejan de hacer cualquier cosa, pero se sientan en segundo plano y el "asesino sin memoria" los matará cuando necesite memoria para los nuevos.


9

Creo que es más fácil responder esto por el orden de cómo se usa la memoria.

Pregunta 3: ¿Qué pasa con el texto (código) y las secciones de datos, cómo están limitados? El compilador prepara el texto y los datos. El requisito para el compilador es asegurarse de que sean accesibles y empaquetarlos en la parte inferior del espacio de direcciones. El espacio de direcciones accesible estará limitado por el hardware, por ejemplo, si el registro del puntero de instrucciones es de 32 bits, el espacio de direcciones de texto sería de 4 GiB.

Pregunta 2: ¿Cómo se define el límite? ¿Es la memoria RAM total disponible? Después del texto y los datos, el área de arriba es el montón. Con la memoria virtual, el montón prácticamente se puede crecer hasta cerca del espacio de direcciones máx.

Pregunta 1: ¿la pila y el montón tienen un límite de tamaño estático (por ejemplo, 2 gigabytes cada uno), o es este límite dinámico, que cambia de acuerdo con las asignaciones de memoria durante la ejecución del programa (es decir, 4 gigabytes en total para ser utilizados por ambos, entonces si un programa solo usa la pila, ¿podrá tener una pila con 4 gigabytes? El segmento final en el espacio de direcciones del proceso es la pila. La pila toma el segmento final del espacio de direcciones y comienza desde el final y crece hacia abajo .

Debido a que el montón crece y la pila baja, básicamente se limitan entre sí. Además, debido a que ambos tipos de segmentos son grabables, no siempre fue una violación que uno de ellos cruzara el límite, por lo que podría haber desbordamiento de búfer o pila. Ahora hay un mecanismo para evitar que sucedan.

Para empezar, hay un límite establecido para el montón (pila) para cada proceso. Este límite se puede cambiar en tiempo de ejecución (usando brk () / sbrk ()). Básicamente, lo que sucede es que cuando el proceso necesita más espacio de almacenamiento dinámico y se ha quedado sin espacio asignado, la biblioteca estándar emitirá la llamada al sistema operativo. El sistema operativo asignará una página, que generalmente será administrada por la biblioteca del usuario para que el programa la use. Es decir, si el programa quiere 1 KiB, el sistema operativo le dará 4 KiB adicionales y la biblioteca le dará 1 KiB al programa y tendrá 3 KiB para usar cuando el programa solicite más la próxima vez.

La mayoría de las veces el diseño será Texto, Datos, Montón (crece), espacio no asignado y finalmente Pila (crece hacia abajo). Todos comparten el mismo espacio de direcciones.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.