Me he encontrado con pérdidas de memoria muchas veces. Por lo general, cuando estoy malloc
hablando como si no hubiera mañana, o colgando FILE *
es como ropa sucia. Generalmente asumo (léase: espero desesperadamente) que toda la memoria se limpia al menos cuando el programa termina. ¿Hay situaciones en las que la memoria filtrada no se recopilará cuando el programa finalice o se bloquee?
Si la respuesta varía mucho de un idioma a otro, centrémonos en C (++).
Tenga en cuenta el uso hiperbólico de la frase, "como si no hubiera mañana" y "colgando ... como ropa sucia". La inseguridad * malloc
* puede dañar a sus seres queridos. Además, tenga cuidado con la ropa sucia.
c++
c
memory
memory-leaks
DilithiumMatrix
fuente
fuente
calloc
gustaría que no hubiera mañana. Excelente.Respuestas:
No. Los sistemas operativos liberan todos los recursos retenidos por los procesos cuando salen.
Esto se aplica a todos los recursos que mantiene el sistema operativo: memoria, archivos abiertos, conexiones de red, identificadores de ventanas ...
Dicho esto, si el programa se ejecuta en un sistema integrado sin un sistema operativo, o con un sistema operativo muy simple o con errores, la memoria podría no ser utilizable hasta que se reinicie. Pero si estuviera en esa situación, probablemente no estaría haciendo esta pregunta.
El sistema operativo puede tardar mucho en liberar ciertos recursos. Por ejemplo, el puerto TCP que utiliza un servidor de red para aceptar conexiones puede tardar unos minutos en liberarse, incluso si el programa lo cierra correctamente. Un programa en red también puede contener recursos remotos como objetos de base de datos. El sistema remoto debería liberar esos recursos cuando se pierde la conexión de red, pero puede tardar incluso más que el sistema operativo local.
fuente
ipcrm
una limpieza manual, linux.die.net/man/8/ipcrm .El estándar C no especifica que la memoria asignada por
malloc
se libera cuando el programa termina. Esto lo hace el sistema operativo y no todos los sistemas operativos (generalmente están en el mundo integrado) liberan la memoria cuando el programa termina.fuente
main
devuelve,malloc
se libera toda la memoria asignada por . Por ejemplo, dice que todos los archivos abiertos se cierran antes de que finalice el programa. Para la memoria asignada mymalloc
, simplemente no se especifica. Ahora, por supuesto, mi oración con respecto al sistema operativo describe lo que generalmente se hace, no lo que prescribe el Estándar, ya que no especifica nada sobre esto.std::atexit
también considera la terminación del programa víastd::exit
, y luego también estástd::abort
y (específico de C ++)std::terminate
.atexit
no sería utilizable. :-)Como todas las respuestas han cubierto la mayoría de los aspectos de su pregunta sobre los sistemas operativos modernos, pero históricamente, hay uno que vale la pena mencionar si alguna vez ha programado en el mundo de DOS. Los programas Terminante y Permanente Residente (TSR) generalmente devuelven el control al sistema, pero residen en la memoria que podría reactivarse por una interrupción de software / hardware. Era normal ver mensajes como "¡sin memoria! Intenta descargar algunos de tus TSR" cuando trabaja en estos sistemas operativos.
Entonces técnicamente el programa termina , pero debido a que aún reside en la memoria, cualquier pérdida de memoria no se liberará a menos que descargue el programa.
Por lo tanto, puede considerar que este es otro caso, además de que los sistemas operativos no recuperan la memoria, ya sea porque tiene errores o porque el sistema operativo integrado está diseñado para hacerlo.
Recuerdo un ejemplo más. Customer Information Control System (CICS), un servidor de transacciones que se ejecuta principalmente en mainframes IBM es pseudo-conversacional. Cuando se ejecuta, procesa los datos ingresados por el usuario, genera otro conjunto de datos para el usuario, se transfiere al nodo terminal del usuario y finaliza. Al activar la tecla de atención, vuelve a reactivarse para procesar otro conjunto de datos. Debido a la forma en que se comporta, técnicamente nuevamente, el sistema operativo no recuperará memoria de los Programas CICS terminados, a menos que recicle el servidor de transacciones CICS.
fuente
Como han dicho los demás, la mayoría de los sistemas operativos recuperarán la memoria asignada al finalizar el proceso (y probablemente otros recursos como sockets de red, identificadores de archivos, etc.).
Dicho esto, es posible que la memoria no sea lo único de lo que deba preocuparse cuando trabaje con new / delete (en lugar de raw malloc / free). La memoria asignada en nuevo puede ser reclamada, pero las cosas que se pueden hacer en los destructores de los objetos no sucederán. Quizás el destructor de alguna clase escribe un valor centinela en un archivo al ser destruido. Si el proceso simplemente termina, el identificador del archivo puede vaciarse y la memoria recuperada, pero ese valor centinela no se escribiría.
Moraleja de la historia, siempre limpia después de ti mismo. No dejes que las cosas cuelguen. No confíe en la limpieza del sistema operativo después de usted. Limpia después de ti mismo.
fuente
kill -9
aparezca un fan menos que brillante ...)std::exit
llamará a dtors,std::abort
no lo hará, las excepciones no detectadas podrían.Es más probable que esto dependa del sistema operativo que del idioma. En última instancia, cualquier programa en cualquier idioma obtendrá su memoria del sistema operativo.
Nunca he oído hablar de un sistema operativo que no recicla la memoria cuando un programa se cierra o falla. Entonces, si su programa tiene un límite superior en la memoria que necesita asignar, entonces simplemente asignar y nunca liberar es perfectamente razonable.
fuente
Si el programa alguna vez se convierte en un componente dinámico ("complemento") que se carga en el espacio de direcciones de otro programa, será problemático, incluso en un sistema operativo con una gestión de memoria ordenada. Ni siquiera tenemos que pensar en la portabilidad del código a sistemas menos capaces.
Por otro lado, liberar toda la memoria puede afectar el rendimiento de la limpieza de un programa.
Un programa en el que estaba trabajando, cierto caso de prueba, requirió 30 segundos o más para que el programa saliera, porque estaba recursándose a través del gráfico de toda la memoria dinámica y liberándolo pieza por pieza.
Una solución razonable es tener la capacidad allí y cubrirla con casos de prueba, pero desactivarla en el código de producción para que la aplicación se cierre rápidamente.
fuente
Todos los sistemas operativos que merecen el título limpiarán el desorden que hizo su proceso después de la terminación. Pero siempre hay imprevistos, ¿qué pasa si de alguna manera se le negó el acceso y algún mal programador no previó la posibilidad y no vuelve a intentarlo un poco más tarde? Siempre es más seguro limpiar usted mismo SI las fugas de memoria son críticas; de lo contrario, no vale la pena el esfuerzo, en mi opinión, si ese esfuerzo es costoso.
Editar: necesita limpiar las pérdidas de memoria si están en un lugar donde se acumularán, como en bucles. Las pérdidas de memoria de las que hablo son las que se acumulan en un tiempo constante durante el transcurso del programa, si tiene una fuga de cualquier otro tipo, lo más probable es que tarde o temprano sea un problema grave.
En términos técnicos, si sus fugas son de 'complejidad' de memoria O (1) están bien en la mayoría de los casos, O (logn) ya son desagradables (y en algunos casos fatales) y O (N) + intolerables.
fuente
La memoria compartida en sistemas que cumplen con POSIX persiste hasta que se llama a shm_unlink o se reinicia el sistema.
fuente
Si tiene comunicación entre procesos, esto puede llevar a que otros procesos nunca se completen y consuman recursos según el protocolo.
Para dar un ejemplo, una vez estaba experimentando con la impresión en una impresora PDF en Java cuando terminé la JVM en medio de un trabajo de impresora, el proceso de cola de PDF permaneció activo y tuve que eliminarlo en el administrador de tareas antes de poder hacerlo. vuelva a intentar la impresión.
fuente