2008-10-25 12 views
7

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 utilizarse para la siguiente llamada a malloc.Desasignación de memoria UNIX vs Windows

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?

EDIT: 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).

+0

Los procesos que disminuyen en tamaño en Windows pueden ser otra cosa: Windows recorta el tamaño del conjunto residente cuando se minimiza una ventana, y probablemente estaba viendo ese valor en el administrador de tareas. Firefox, por ejemplo, tuvo que deshabilitar esa "característica" de Windows, que ralentizó demasiado. – CesarB

Respuesta

14

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 de uno de estos fragmentos grandes debe liberarse 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, tiene 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 expande tradicionalmente 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 trozo de memoria del sistema operativo, que puede colocarse en cualquier lugar del espacio de 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, solicitando memoria del sistema operativo y subdividiéndola de la forma en que querer (o a veces pedir 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.

2

A partir de este artículo Memory Management

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 acerca de la desasignación de memoria de Windows.

Dicho esto, puede intentar y Emulating UNIX Memory Management Under Microsoft Windows, mediante la implementación de llamadas de sistema de bajo nivel sbrk y mmap/munmap en Windows.

1

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 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).

6

Nota que sé mucho más acerca de Windows a Unix en lo que sigue ...

Lo que en realidad sucede con la asignación de memoria y cancelación de asignación no es exactamente lo que usted describe, 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 no puede acceder previamente al espacio de direcciones virtuales no 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 subproceso 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í.

4

Todo depende de la biblioteca C runtime que utilice. 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() sería en trozos muy pequeños)

Recientemente, Mozilla Firefox tomó prestada una implementación malloc() de * OS BSD. 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.

2

El único sistema operativo en el que no se puede dar fácilmente la memoria asignada de nuevo al sistema es OS X - citando Firefox 3 Memory Usage:

Después de extensas pruebas y confirmación por parte de los empleados de Apple que dimos cuenta de que no había camino para un asignador para dar páginas no utilizadas de la memoria espalda, manteniendo la dirección rango reservado .. (Usted puede desasignar ellos y reasignar ellos, pero eso hace que algunos condiciones de carrera y no es tan performant.) Hay APIs t reclamo de sombrero para hacerlo (ambos madvise() y msync()) pero en realidad no hacen nada.

2

Como se mencionó anteriormente, esto está más vinculado a la implementación de malloc que 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 más precisos, lo que necesita saber la diferencia entre la memoria física, memoria virtual, etc ... Esto está bien explicado aquí:

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

1

Otros los carteles han comentado sobre el ángulo específico de la plataforma. Pero como usted pregunta específicamente sobre malloc, veamos lo que dice el Estándar C:

"La función libre hace que el espacio apuntado por ptr sea desasignado, es decir, que se haga disponible para una asignación posterior."

Que parece un requisito bastante claro que la memoria no se devuelve al sistema operativo.De vez en cuando ves programas de depender 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 cuestión ha surgido en comp.lang.c, algunos críticos han señalado esta sección:

"La función devuelve un malloc 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.

0

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 de la norma es que la memoria no se devuelve el SO.

Cuestiones relacionadas