tipos sistemas procesos operativos memoria gestion administracion windows language-agnostic unix memory-management

sistemas - Desasignación de memoria de UNIX frente a Windows



memoria virtual (9)

Como se mencionó anteriormente, esto está más relacionado con la implementación de malloc que con el sistema operativo per se. En Linux, con glibc, la memoria siempre se devuelve al sistema operativo por encima de cierto tamaño: glibc malloc usa mmap para grandes asignaciones (controlado por MMAP_THRESHOLD), y en ese caso, llamadas gratuitas munmap, que libera automáticamente la memoria reservada. Por debajo de ese umbral, usa brk, y free no "devuelve" la memoria en ese caso.

Tenga en cuenta que la explicación anterior no es exacta: para ser precisos, debe saber la diferencia entre la memoria física, la memoria virtual, etc. Esto se explica bien aquí:

http://blogs.msdn.com/oldnewthing/archive/2004/08/22/218527.aspx

Según tengo entendido, en Unix, cuando se libera la memoria, la memoria no se devuelve al sistema operativo, sino que permanece en el proceso para volver a usarse para la siguiente llamada a malloc.

En Windows, entiendo que la memoria realmente se devuelve al sistema operativo.

¿Hay alguna gran diferencia entre estas dos formas de hacer las cosas o son solo dos formas diferentes de hacer lo mismo? Y si hay algún pros / contras para estos dos métodos, ¿qué son?

EDITAR: Gracias por la aclaración. Siempre pensé que esto era algo del sistema operativo (ya que los procesos nunca parecen disminuir de tamaño en sistemas tipo UNIX, pero sí en Windows).


De este artículo de gestión de la memoria

Malloc normalmente no devuelve la memoria liberada al sistema operativo; sigue siendo propiedad del proceso hasta que finaliza. El proceso puede reutilizarlo la próxima vez que solicite más memoria, pero otros programas no tendrán acceso a él, incluso si no hay otra memoria disponible. Como corolario, entonces, la huella de memoria de un programa es el tamaño de la (s) asignación (es) más grande (s) realizada (s) en un momento dado. Por lo tanto, siempre es aconsejable liberar objetos que no necesita, especialmente los más grandes tan pronto como sea posible, para minimizar esta huella.

Ese artículo sugiere que en Windows, al menos para el programa C, la memoria no se devuelve al sistema operativo.

Así que no estoy seguro acerca de su generalización sobre la desasignación de memoria de Windows.

Dicho esto, puede intentar Emular la Administración de memoria de UNIX en Microsoft Windows , implementando llamadas de sistema de bajo nivel sbrk y mmap / munmap en Windows.


El único sistema operativo donde no se puede devolver fácilmente la memoria asignada al sistema es OS X, citando el uso de la memoria de Firefox 3 :

Después de extensas pruebas y confirmaciones por parte de los empleados de Apple, nos dimos cuenta de que no había forma de que un asignador devolviera páginas de memoria no utilizadas manteniendo el rango de direcciones reservado. (Puede desasignarlas y reasignarlas, pero eso causa algunas condiciones de carrera y ''t como rendimiento.) Hay API que afirman hacerlo (tanto madvise () como msync ()) pero en realidad no hacen nada.


No hay mucha diferencia entre Windows y Unix con respecto a eso.

En ambos, hay dos niveles de asignación. El sistema operativo asigna memoria al proceso en trozos grandes (una página o más, en x86, el tamaño de página suele ser 4096 bytes). Las bibliotecas de tiempo de ejecución, que se ejecutan dentro del proceso, subdividen este espacio y asignan partes de él a su código.

Para devolver la memoria al sistema operativo, primero toda la memoria asignada desde uno de estos grandes fragmentos debe ser liberada a la biblioteca de tiempo de ejecución. La biblioteca de tiempo de ejecución puede, si así lo desea, indicarle al sistema operativo que libere ese trozo de memoria.

En Linux, tienes brk y mmap . brk controla el tamaño de una gran cantidad de memoria asignada a su proceso; puede expandirlo o reducirlo, pero solo en un extremo. malloc tradicionalmente expande este trozo de memoria cuando necesita más memoria para asignar, y la reduce cuando es posible. Sin embargo, encogerse no es fácil; requiere una sola asignación inoportuna de un byte al final para que no se pueda reducir incluso si todo lo anterior a esa asignación se ha liberado. Esta es la fuente del meme "Unix no libera memoria".

Sin embargo, también hay mmap anónimo. Anonymous mmap solicita un fragmento de memoria del sistema operativo, que puede colocarse en cualquier lugar del espacio de la memoria de proceso. Este trozo se puede devolver fácilmente cuando ya no se necesita, incluso si hay asignaciones posteriores que aún no se han lanzado. malloc usa también mmap (particularmente para grandes asignaciones, donde un trozo completo de memoria puede devolverse fácilmente después de ser liberado).

Por supuesto, tanto en Windows como en Linux, si no le gusta el comportamiento del asignador de memoria (o asignadores) de las bibliotecas de tiempo de ejecución, puede usar el suyo propio, solicitar memoria del sistema operativo y subdividirla de la manera que desee (o algunas veces pidiendo memoria de otro asignador, pero en bloques más grandes). Un uso interesante es tener un asignador para toda la memoria asociada con una tarea (por ejemplo, una solicitud del servidor web), que se descarta por completo al final de la tarea (sin necesidad de liberar todas las piezas individualmente); Otro uso interesante es un asignador para objetos de tamaño fijo (por ejemplo, objetos de cinco bytes), que evita la fragmentación de la memoria.


No sé acerca de Windows pero, en UNIX, la llamada brk() se usa para traer más memoria al espacio de direcciones para usar con las llamadas malloc() .

Nunca he visto esta memoria devuelta al sistema operativo hasta que finaliza el proceso. Por lo general, puede ver esto con herramientas como la top .

Sospecho que el comportamiento sería el mismo para Windows, pero sé que Windows tiene otras funciones de asignación que malloc() que pueden hacer esto (parte de la API de Win32).


Otros carteles han comentado sobre el ángulo específico de la plataforma. Pero ya que preguntas específicamente sobre Malloc, veamos lo que dice el Estándar C:

"La función gratuita hace que el espacio apuntado por ptr sea desasignado, es decir, esté disponible para una asignación posterior".

Lo cual parece un requisito bastante claro de que la memoria no se devuelve al sistema operativo. Ocasionalmente ve programas que dependen de este comportamiento:

int main(void) { void *p = malloc(AS_MUCH_MEMORY_AS_I_WILL_EVER_NEED); if (p != 0) { free(p); /* malloc should always work for rest of program */ } }

Sin embargo, cuando esta pregunta ha surgido en comp.lang.c, algunos carteles han señalado esta sección:

"La función malloc devuelve un puntero nulo o un puntero al espacio asignado".

Esto sugiere que cualquier llamada a malloc puede fallar. Parece que la intención del Estándar es que la memoria no se devuelva al sistema operativo, pero el problema no es 100% seguro a los ojos de los abogados de idiomas.


Tenga en cuenta que sé mucho más sobre Windows que sobre Unix en lo que sigue ...

Lo que realmente ocurre con la asignación de memoria y la desasignación no es exactamente lo que describes, en cualquier caso. Esto se debe a que hay dos conceptos muy diferentes en juego aquí: la memoria física que posee la computadora y el espacio de direcciones virtuales del programa, la memoria que su programa cree que puede usar.

Cuando su programa solicita más memoria del sistema operativo, lo que realmente está sucediendo es que el programa ya no puede acceder al espacio de direcciones virtuales que antes no estaba disponible en su programa. Los sistemas operativos modernos no funcionan con solo tener un conjunto de memoria "real" (es decir, física) que entrega a los procesos cuando realizan una solicitud de asignación: mantiene el espacio de direcciones virtuales para cada programa en ejecución y, cuando los programas realmente acceden a partes de ese espacio de direcciones virtuales, aseguran que esto se mapee a alguna memoria física, posiblemente intercambiando una parte del espacio de direcciones de otro programa con el archivo de intercambio en el disco.

Como ejemplo de esto, en Windows cada hilo comienza con (por defecto) un megabyte de espacio de pila asignado para él. Esto no significa que cada hilo consuma un megabyte de la memoria física de la máquina: es simplemente que el espacio de direcciones está configurado para que esté disponible para su uso. En este sentido, realmente no funciona pensar en el sistema operativo que le da a la memoria de su programa y luego en el programa que lo devuelve, simplemente no funciona así.


Todo depende de la biblioteca C runtime que use. No hay manera específica de UNIX o manera de WINDOWS. Cada proveedor de compiladores (HP, SUN, MS, GNU) viene con su propia biblioteca de tiempo de ejecución que contiene la lógica para malloc. cada implementación de malloc funcionará igual / diferente dependiendo del sistema operativo. Ni UNIX / LINUX / Windows necesita un "ENVÍO REAL" de la memoria al sistema operativo. Eso sería demasiado caro (ya que su alloc () estaría en pedazos muy pequeños)

Recientemente, Mozilla Firefox tomó prestada una implementación malloc () de * BSD OS. Eligieron utilizar un malloc diferente de lo que vendía su proveedor del compilador (múltiples en este caso, gcc y VC ++). Como querían un cierto comportamiento, obtuvieron lo que querían.


La función malloc devuelve un puntero nulo o un puntero al espacio asignado. "

Esto sugiere que cualquier llamada a malloc puede fallar. Parece que la intención del estándar es que la memoria no se devuelva al sistema operativo.