2011-01-26 25 views
5

En mi programa escrito con C y C++, voy a crear un objeto nuevo para completar la tarea y luego eliminar el objeto.Cómo evitar la pérdida de memoria cuando el usuario presiona ctrl + c en Linux?

En el momento después de nuevo objeto pero antes objeto de eliminación, si el usuario presiona ctrl +c para romper el proceso, que hará que no elimina para ser llamado y se produce una pérdida de memoria.

¿Qué debo hacer para evitar esta situación?

Además, si la memoria fue recuperada por el sistema operativo, ¿qué ocurre con los archivos abiertos? ¿Están cerrados por el sistema operativo o debo cerrarlos manualmente?

+0

alguien puede por favor s/Linux/Unix/generalizar esto? –

Respuesta

7

En un sistema basado en memoria virtual, toda la memoria se devuelve al sistema operativo cuando finaliza un proceso, independientemente de si se liberó explícitamente en el código de la aplicación. Sin embargo, es posible que no ocurra lo mismo con otros recursos, que es posible que desee liberar limpiamente. En ese caso, debe proporcionar un controlador de señal personalizado para la señal SIGINT (que se recibe con Ctrl + C), consulte p. Ej. http://linux.die.net/man/2/sigaction.

+0

¿Eso significa que no me debería importar la memoria asignada? Pero descubrí que mi destructor no había sido llamado. ¿El SO también cerró el archivo abierto? – PDF1001

+0

@ PDF1001- Incluso si el sistema operativo hace parte del trabajo por usted, siempre es una buena idea limpiar todo lo que pueda. El sistema operativo no llamará a sus destructores, sino que liberará directamente toda la memoria que asignó su programa. Si recuerdo bien, estás solo cuando se trata de manejadores de archivos. En caso de duda, vaya a lo seguro y no suponga que el sistema operativo hará nada de eso. – bta

1

El sistema operativo reclamará la memoria asignada por el proceso cuando el proceso finalice como resultado de Ctrl-C u otro medio.

7

pulsar Ctrl C enviará un SIGINT al proceso, que por defecto hace una parada en su mayoría-ordenada, incluyendo derribando el administrador de memoria y la liberación de todos montón asignado y la pila. Si necesita realizar otras tareas, deberá instalar un controlador SIGINT y realizar las tareas usted mismo.

2

Cuando se presiona CTRL + C en una consola Linux, la señal SIGINT se envía a la aplicación que, si la señal no tiene controlador, terminará el programa devolviendo toda la memoria al sistema operativo. Esto, por supuesto, haría inútil liberar la memoria, ya que toda la memoria se liberará una vez que el programa exista. Sin embargo, si desea manejar la señal CTRL + C SIGINT (tal vez para escribir algunos últimos datos en un archivo o hacer alguna otra limpieza), puede usar la función signal() para instalar una función que se llamará cuando se reciba la señal . Consulte la página de manual para esta función si desea obtener más información.

2

Si asignó cualquier Segmento de memoria compartida SYSV utilizando shmget(2), debe limpiarlo con shmctl(2).

Si asignó cualquier Segmento de memoria compartida POSIX usando shm_open(3), entonces debe limpiarlo usted mismo con shm_unlink(3).

Ambos segmentos de memoria compartida SYSV y POSIX persisten después de la finalización del proceso. Puede ver lo que persiste utilizando la herramienta ipcs(1).

Por supuesto, si no ha utilizado ningún segmento de memoria compartida SYSV o POSIX, entonces todo esto es solo ruido. :)

2

Si el proceso se cierra, normalmente NO se producirá una pérdida de memoria.

La mayor parte de la memoria que asigna se liberará con Ctrl + C. Si ve que el uso de la memoria no vuelve a su nivel anterior, es casi seguro que sea causado por bloques del sistema de archivos almacenados en el búfer.

Sin embargo, se debe sin duda las cosas limpias arriba, especialmente si usted ha usado cualquier otro tipo de recursos:

  • Los archivos creados en los directorios temporales no se eliminarán. Esto incluye/dev/shm, dejando un archivo de este tipo podría considerarse una "pérdida de memoria".
  • Los segmentos de memoria compartida del sistema V o posix no se descartarán cuando finalice su proceso. Si esto te molesta, límpialos específicamente. Alternativamente, límpielos en una ejecución posterior.

Normalmente una fuga (de un objeto de archivo, por ejemplo, persistente o semi-persistente) No importa si una ejecución posterior no se escape más memoria. Por lo tanto, limpiar en una carrera futura es suficiente.

Imagine un proceso que se ejecuta cada 5 minutos desde "cron", si falla en cada ejecución y deja un poco de desorden, sigue estando bien siempre que cada ejecución limpie el desorden del colapso anterior.

0

Se suscriben a una idea errónea bastante común de que los bloques de bloques que no se liberan, pero que aún están accesibles en el momento en que existe un programa, son fugas. Esto no es verdad. Los bloques filtrados son aquellos a los que ningún puntero todavía hace referencia, por lo tanto no pueden liberarse.

A través de los años de jugar con (y romper) muchos kernels perfectamente buenos, nunca he logrado romper suficientemente un administrador de memoria virtual hasta el punto en que ya no recupera el espacio completo de direcciones de un proceso una vez que salió. A menos que esté trabajando con un núcleo claramente marcado como "nuevo y experimental", tendrá más suerte ganando la lotería que encontrar un sistema que no emplee un administrador de memoria virtual efectivo.

No pongas cruft en tu código solo para obtener una puntuación perfecta en Valgrind. Si no tiene tareas de limpieza reales para hacer otra que liberar la memoria que todavía tiene referencias válidas, no necesita molestarse. Si alguien lanza un kill -9 a su programa, no podrá manejarlo y verá que se repite el comportamiento antiguo.

Si tiene descriptores de archivos para limpiar, bloqueos compartidos para renunciar, flujos para purgar o cualquier otra cosa que deba suceder para que otros procesos no te echen de menos cuando te vayas, por supuesto, ocúpate de eso. Simplemente no vayas a agregar código que no hace nada para resolver un problema, simplemente parece una tontería hacerlo.

Nota

Esto fue originalmente iba a ser un comentario, pero es demasiado largo y SO frunce el ceño sobre cómo escribir una novela uno de los comentarios a la vez.

Cuestiones relacionadas