sistemas segmentacion recomendada para paginacion operativos memoria funciona configurar como 8gb 4gb operating-system stack heap virtual-memory

operating-system - segmentacion - memoria virtual windows 7



¿Dónde se colocan varias pilas y montones en la memoria virtual? (2)

Asumiré que tiene los elementos básicos en su núcleo hecho, un controlador de trampas para fallas de página que pueden asignar una página de memoria virtual a la RAM. En el siguiente nivel, necesita un administrador de espacio de direcciones de memoria virtual desde el cual el código de modo de usuario puede solicitar espacio de direcciones. Elija una granularidad de segmento que evite la fragmentación excesiva, 64 KB (16 páginas) es un buen número. Permita que el código del modo de usuario reserve espacio y comente el espacio. Un simple mapa de bits de 4GB / 64KB = 64K x 2 bits para realizar un seguimiento del estado del segmento hace el trabajo. El manejador de captura de fallas de página también necesita consultar este mapa de bits para saber si la solicitud de página es válida o no.

Una pila es una asignación de VM de tamaño fijo, generalmente 1 megabyte. Por lo general, un hilo solo necesita un puñado de páginas, dependiendo del nivel de anidación de la función, así que reserve 1MB y comprometa solo las primeras páginas. Cuando el hilo anide más profundo, se saltará un error de página y el núcleo simplemente puede asignar la página extra a la RAM para permitir que el hilo continúe. Querrá marcar las últimas páginas como especiales, cuando la página del hilo falle sobre ellas, declara el nombre de este sitio web.

El trabajo más importante del administrador de montón es evitar la fragmentación. La mejor manera de hacerlo es crear una lista de apariencia que particione las solicitudes de almacenamiento dinámico por tamaño. Todo menos de 8 bytes proviene de la primera lista de segmentos. 8 a 16 del segundo, 16 a 32 del tercero, etcétera. Aumentando el tamaño del cubo a medida que sube. Tendrás que jugar con los tamaños de cubo para obtener el mejor equilibrio. Las asignaciones muy grandes provienen directamente del administrador de direcciones de VM.

La primera vez que se golpea una entrada en la lista de lookaside, se asigna un nuevo segmento VM. Usted subdivide el segmento en bloques más pequeños con una lista vinculada. Cuando se libera tal asignación, agrega el bloque a la lista de bloques libres. Todos los bloques tienen el mismo tamaño, independientemente de la solicitud del programa, por lo que no habrá fragmentación. Cuando el segmento se utiliza por completo y no hay bloques libres disponibles, se asigna un nuevo segmento. Cuando un segmento no contiene nada más que bloques libres, puede devolverlo al administrador de VM.

Este esquema le permite crear cualquier cantidad de pilas y montones.

Estoy escribiendo un núcleo y necesito (y quiero) poner múltiples pilas y montones en la memoria virtual, pero no puedo encontrar la manera de ubicarlos de manera eficiente. ¿Cómo lo hacen los programas normales?

¿Cómo (o dónde) están las pilas y los montones colocados en la memoria virtual limitada proporcionada por un sistema de 32 bits, de modo que tengan el mayor espacio de crecimiento posible?

Por ejemplo, cuando se carga un programa trivial en la memoria, el diseño de su espacio de direcciones puede verse así:

[ Code Data BSS Heap-> ... <-Stack ]

En este caso, el montón puede crecer tanto como la memoria virtual lo permita (por ejemplo, hasta la pila), y creo que así es como funciona el montón para la mayoría de los programas. No hay un límite superior predefinido.

Muchos programas tienen bibliotecas compartidas que se colocan en algún lugar del espacio de direcciones virtuales. Luego hay programas de subprocesos múltiples que tienen varias pilas, una para cada hilo. Y los programas .NET tienen múltiples montones , todos los cuales tienen que poder crecer de una forma u otra.

Simplemente no veo cómo esto se hace razonablemente eficiente sin poner un límite predefinido en el tamaño de todos los montones y pilas.


En pocas palabras, como los recursos de su sistema siempre son finitos, no puede ir sin límites.

La gestión de la memoria siempre consta de varias capas, cada una de las cuales tiene una responsabilidad bien definida. Desde la perspectiva del programa, el administrador de nivel de aplicación es visible y generalmente solo se ocupa de su propio montón asignado único. Un nivel anterior podría tratar de crear montones múltiples si fuera necesario de (un) montón global y asignarlos a subprogramas (cada uno con su propio administrador de memoria). Por encima podría ser el estándar malloc() / free() que utiliza y, por encima de ellos, el sistema operativo que trata las páginas y la asignación real de memoria por proceso (básicamente, no se trata de montones múltiples, sino incluso montones de nivel de usuario en general).

La administración de la memoria es costosa y también atrapa al kernel. La combinación de ambos podría imponer un impacto de rendimiento severo, así que lo que parece ser la administración real del montón desde el punto de vista de la aplicación se implementa realmente en el espacio del usuario (la biblioteca C runtime) por el rendimiento (y por otro motivo fuera de alcance por ahora )

Al cargar una biblioteca compartida (DLL), si está cargada al inicio del programa, por supuesto, será probablemente cargada en CÓDIGO / DATOS / etc para que no se produzca la fragmentación del montón. Por otro lado, si se carga en tiempo de ejecución, no hay prácticamente otra posibilidad que utilizar el espacio de almacenamiento dinámico. Las bibliotecas estáticas están, por supuesto, simplemente vinculadas en las secciones CODE / DATA / BSS / etc.

Al final del día, tendrá que imponer límites a montones y montones para que no se desborden, pero puede asignar otros. Si uno necesita crecer más allá de ese límite, puede

  • Terminar la aplicación con error
  • Haga que el administrador de memoria asigne / redimensione / mueva el bloque de memoria para esa pila / pila y lo más probable es que desfragmente el montón (su propio nivel) después; es por eso que free() generalmente tiene un bajo rendimiento.

Considerando un marco de pila de 1KB bastante grande en cada call como promedio (podría suceder si el desarrollador de la aplicación no tiene experiencia), una pila de 10MB sería suficiente para 10240 call anidadas. Por cierto, además de eso, no hay necesidad de más de una pila y montón por hilo.