2010-06-27 21 views
8

This question me hizo sentir curiosidad. Preguntas como esta siempre obtienen respuestas como "Generalmente es seguro, pero no debes asumir que el sistema operativo hará esto por ti", lo cual me parece un buen consejo, pero me pregunto: ¿hay algún desarrollo activo (lanzado)? sistemas operativos que no hacen esto?¿Qué sistemas operativos no liberarán memoria al salir del programa?

¿Es esto algo que se reparó en la era de los dinosaurios (los 80)?

+0

En Windows hay un problema similar: archivos temporales. La mayoría de los programas que necesitan memoria adicional para sus operaciones (y se ejecutan en computadoras que podrían no tener suficiente memoria) usan archivos temporales. Dado lo fácil que es para un programa fallar, o ser terminado por el usuario, los archivos temporales no se están limpiando. – rwong

Respuesta

10

La respuesta breve es "ninguna". Incluso un programa en DOS hace años liberaría memoria en la terminación del programa (simplemente por la virtud de que nada estaba administrando la memoria cuando el programa se detuvo). Estoy seguro de que alguien puede ver que el código del modo kernel no libera necesariamente su memoria al salir de la aplicación o pueden citar algunos OS incrustados ... pero se puede suponer que la aplicación de salida devuelve toda la memoria adquirida por el código de modo de usuario . (Windows 3.x podría haber tenido este problema dependiendo de qué asignador se usó ...)

La razón de la virtud de que "debería liberar su memoria" es que para la ingeniería de software a gran escala, debe esforzarse por desarrollar componentes que son flexibles en su uso porque nunca se sabe cómo alguien más va a cambiar el uso de su código mucho después de que haya abandonado el equipo.

Piénsalo así. Digamos que diseñas una clase que está diseñada para ser singleton (solo instanciada una vez durante la vida útil de la aplicación). Como tal, usted decide no molestarse con la limpieza de la memoria cuando su componente se destruye o termina. Esa es una decisión perfecta para ese momento. Años más tarde, después de que se haya ido a pastos más verdes, alguien más puede venir y decidir que necesitan usar su clase en varios lugares, de modo que muchas instancias irán y desaparecerán durante la vida útil de la aplicación. Su fuga de memoria se convertirá en su problema.

En mi equipo, a menudo hemos hablado de hacer que el usuario iniciado "cerrar" la aplicación simplemente sea exit() sin hacer ninguna limpieza. Si alguna vez hacemos esto, seguiría exigiendo que el equipo desarrolle clases y componentes que limpien adecuadamente después de ellos mismos.

+0

+1. Me gusta que siguieras diciendo por qué no hay excusa para las pérdidas de memoria. – stinky472

+2

Aunque la memoria será limpiada por el sistema operativo, una llamada directa a 'exit()' puede causar fugas (y por lo tanto no es apropiado como respuesta a "cerrar"). Hay recursos que no son de memoria y que probablemente no serán limpiados por el sistema operativo (como bloqueos de archivos). – Mankarse

1

Ningún sistema operativo similar a Unix reciente no libera toda la memoria de proceso cuando sale un proceso, donde lo más reciente probablemente significa "desde 1970 más o menos". Estoy bastante seguro de que los sistemas operativos de PC muy antiguos como DOS y CP/M tenían este problema, y ​​algunas versiones anteriores de Windows. No sé lo suficiente sobre Windows reciente, pero me sorprendería mucho que Windows XP, Vista o Windows 7 tengan problemas para liberar la memoria del proceso.

Como regla general, yo sugeriría que cualquier sistema operativo que no utiliza memoria virtual para dar a los procesos espacios de direcciones separados es probablemente vulnerable a la pérdida de memoria cuando los procesos fallan de manera importante. Una vez que un sistema operativo ha implementado espacios de direcciones virtuales por proceso, ya tiene que hacer un seguimiento de toda la memoria física asignada a un proceso de todos modos, por lo que liberarlo de manera confiable es sencillo.

Dicho todo esto, a menudo es una buena idea escribir sus programas para limpiarlos de todas formas. Tiende a conducir a subcomponentes mejor diseñados, y también hace que sea más fácil aplicar herramientas que busquen pérdidas de memoria y similares.

+2

DOS no tenía este problema, y ​​dudo que CP/M lo hiciera. La salida del programa simplemente restablece el puntero a dónde asignar memoria, lo que significa que cualquier memoria previamente asignada al programa se sobrescribirá con el próximo programa que se ejecute. –

3

En CP/M, no era una cuestión de liberar memoria tanto, ya que tenía un área estática de RAM para su programa, y ​​cada programa se ejecutaba en el mismo espacio. Entonces, cuando Program A se cerró, y Program B ejecutó, B simplemente se cargó encima de A.

Ahora había mecanismos para reservar memoria lejos del SO, pero esto no era típicamente memoria de montón (en el clásico caso de que lo consideremos hoy), fue diseño de áreas reservadas especiales para diversas tareas.

Por ejemplo, DOS tenía esta rutina de salida llamada "Residir y permanecer residente". Esto "cerró" el programa, pero no lanzó el espacio después de que el programa se cerró. Normalmente, estos programas cargan vectores de interrupción (como interrupciones de teclado) para desencadenar rutinas. Borland Sidekick era un "TSR" muy popular en su época y ofrecía cosas como una calculadora y una lista de contactos.

Finalmente, dado que estos no eran sistemas de memoria protegidos, sus programas podrían abusar del sistema en todo tipo de formas de hacer lo que usted desea, pero esa es una discusión diferente.

+0

Para futuras referencias de lectores: DOS "exit" syscalls 'int 21h (ah = 4ch)', 'int 20h' y' int 21h (ah = 0) 'memoria libre asignada por' int 21h (ah = 48h) ' , a diferencia de "TSR" 'int 21h (ah = 31h)', que no. – Ruslan

Cuestiones relacionadas