¿Maneja condiciones de falta de memoria?

9

¿Qué haces cuando mallocdevuelve 0 o una nueva excepción de lanzamientos? ¿Simplemente detener o intentar sobrevivir a la condición OOM / guardar el trabajo del usuario?

mbq
fuente
44
Relacionado en Stackoverflow stackoverflow.com/questions/763159/…
ysolik
11
Argh Sigo leyendo esto como "sin maná". Demasiados videojuegos en mi pasado, creo. :)
Adam Lear

Respuestas:

4

Evitaría el OOM como evitar un choque.

Evite hacer una gran cantidad de trabajo (y asigne una gran cantidad de memoria) a la vez. Mantenga los datos en el disco, confíe en la memoria caché del disco del sistema operativo y utilice IO mapeado en memoria tanto como sea posible, y solo opere en una pequeña parte de los datos a la vez. Si grandes cantidades de datos necesitan estar en línea (servidos con baja latencia), manténgalos en la memoria en varias máquinas, como hacen todas las grandes compañías de motores de búsqueda. O compra un SSD.

rwong
fuente
Aparentemente esto tiene más sentido.
mbq
2
Hubo un gran debate sobre cómo manejar OOM con gracia (RAII, seguridad de excepción, bla ...) pero una vez me di cuenta de eso en un sistema multiproceso con múltiples módulos dinámicos (algunos de terceros), incluso si su hilo no lo hizo accidente, hay un momento de tiempo desafortunado donde cada hilo verá un OOM. Si incluso uno solo decidió seguir adelante, no puede hacer nada más que ser testigo ocular.
rwong
13

La mayoría de las personas que responden a esta pregunta probablemente nunca hayan trabajado en sistemas embebidos, donde malloc devuelve 0 es una posibilidad muy real. En un sistema en el que estoy trabajando actualmente, hay un total de 4.25K bytes de RAM (4352 bytes). Estoy asignando 64 bytes para la pila, y actualmente tengo un montón de 1600 bytes. Justo ayer estaba depurando una rutina de paseo dinámico para poder seguir la asignación y la liberación de memoria. La caminata de almacenamiento dinámico utiliza un búfer pequeño (30 bytes) asignado estáticamente para enviar a un puerto serie. Se desactivará para la versión de lanzamiento.

Como se trata de un producto de consumo, es mejor que no se quede sin memoria una vez que se haya lanzado el producto. Estoy seguro de que lo hará durante el desarrollo. En cualquier caso, todo lo que puedo hacer es hacer sonar el parlante un par de veces y forzar un reinicio.

tcrosley
fuente
2
Encajar funcionalidades dentro de un espacio pequeño es increíble ... es una forma de arte como el bonsái
rwong
66
Muchos proyectos en sistemas embebidos simplemente prohíben la asignación dinámica de memoria. El único caso de OOM sigue siendo el desbordamiento de pila.
Mouviciel
Tienes razón, pero especialmente con tu primera oración: la mayoría de esto simplemente no es relevante para la mayoría de los desarrolladores por suerte.
Konrad Rudolph
4

Para ser honesto, en todos los proyectos que he realizado (tenga en cuenta que todavía no estoy trabajando en ningún lado), nunca he considerado que podría suceder, y por lo tanto supongo que mis programas morirían muy rápidamente.

Además, manejar un OOM requiere que haya asignado previamente los recursos para mostrar el mensaje de error o guardar todo, lo que puede ser un poco inconveniente.

Siento que en estos días, la memoria cuesta menos que el maní, no es algo que deba ocurrir con frecuencia. En los albores de la memoria protegida y antes, tal vez eso era una preocupación, ¿pero ahora? Los únicos errores de OOM que he visto fueron de código con errores.

zneak
fuente
Puedo pensar en recuperar parte de la memoria que el proceso ya tiene e intentar sobrevivir y recuperarla (una difícil si arrojaste algo útil) o sobrevivir como datos + remanentes que intentan salvarla.
mbq
2

Verificar los códigos de retorno de malloc es inútil de todos modos.

Los sistemas operativos modernos sobrecomprometen la memoria: proporcionan a los procesos más memoria de la que está realmente disponible. La memoria que se le otorga a su proceso es virtual, todo asignado a una sola página puesta a cero.

No es sino hasta que escribe en la memoria que se asigna una página física y única para sus procesos. Si esta asignación falla, el núcleo terminará un proceso (¡quizás el suyo!) En un intento de encontrar memoria. En ese momento ya no hay nada que puedas hacer.

Kristof Provost
fuente
Tuve una idea de entrar en el ciclo while con un largo sueño en el interior, y posiblemente recuperarme si el proceso sobreviviera al asesino de OOM. Tengo la impresión de que los procesos se terminaron debido a su intento de usar la dirección 0, pero no he realizado ninguna prueba sólida.
mbq
No necesita hacer nada especial para lidiar con el asesino OOM. Si su proceso lo activó pero no fue seleccionado, nunca lo sabrá. Todo funcionará como si hubiera suficiente memoria. Si, por otro lado, se selecciona su proceso, finalizará y tampoco hay nada que pueda hacer al respecto.
Kristof Provost
Pero puedo intentar esperar a que OOM libere algo de memoria y luego tratar de asignar nuevamente y continuar. Tengo la impresión de que malloc / new no está esperando que esto suceda.
mbq
No puedes. Su asignación siempre tendrá éxito. Obtendrá toda la memoria virtual que desee. No es hasta que lo tocas que se asigna la memoria física. Tan pronto como toque una página no asignada, su proceso se suspenderá. El núcleo buscará más memoria, lo que podría llevarlo a matar un proceso para obtener más memoria. Si eso tiene éxito (¡y no mata al tuyo!), La página se asignará y tu proceso se reanudará. No hay forma de que su proceso sepa que esto ha sucedido.
Kristof Provost
2
Estoy bastante seguro de que Windows nunca se compromete demasiado. Puede confirmar más que la RAM, pero no más que RAM + swapfile.
CodesInChaos
2

A menos que esté desarrollando sistemas embebidos, sistemas en tiempo real o sistemas que son tan críticos que las fallas pueden costar vidas o miles de millones de dólares ... Entonces, probablemente no valga la pena preocuparse por las condiciones de falta de memoria.

En la mayoría de los casos, de todos modos, es poco lo que se puede hacer cuando no tiene memoria, ya que no hay memoria para crear objetos nuevos o realizar tareas que puedan hacer algo. Debe sopesar el costo de la aplicación que maneja OOM versus el beneficio que obtiene al hacerlo.

Erik Funkenbusch
fuente
Los sistemas en tiempo real no necesitan verificar más acerca de una falla de malloc que los otros sistemas.
zneak
@zneak: falso. Los sistemas en tiempo real tienen que ser predecibles y la falta de memoria no es predecible a menos que lo esté planeando específicamente.
Erik Funkenbusch
Entonces, ¿qué más vas a hacer una vez que llegues a la OOM?
zneak
Memoria libre, procesos de cancelación, etc. Un sistema en tiempo real generalmente no tiene memoria virtual o sistema de intercambio porque tiene que ser determinista. Por lo tanto, puede quedarse sin memoria mucho más fácilmente.
Erik Funkenbusch
Dada una cierta ruta de código que inevitablemente conducirá a un error OOM, no veo cómo el bloqueo es un enfoque menos determinista que liberar memoria y cancelar procesos.
zneak
1

Siempre verificaría si hay errores. Si algo devuelve una condición de error, entonces debe ser manejado por su programa. Incluso si se trata de un mensaje que dice "¡Sin memoria, tengo que irme!", Es mejor que "Infracción de acceso", "rechazado de núcleo" o lo que sea. Uno es una condición de error que manejas, el otro es un error. Y el usuario también lo percibirá como tal.

Para su caso específico, podría intentar revertir la operación, liberando los recursos que ha asignado hasta llegar al punto de falla, informando el error y continuando la ejecución (tal vez cuando intente salir de la aplicación, puede dar el opción para salir de inmediato). De esta forma, el usuario puede decidir qué hacer o tratar de liberar algo de memoria jugando, cerrando archivos, etc. Por supuesto, la forma en que puede manejar la situación depende en gran medida de su programa, un programa que se supone que no debe ser interactivo probablemente solo necesite registrar el error y salir o continuar.

Dysaster
fuente