75

He estado programando durante mucho tiempo, y los programas que veo, cuando se quedan sin memoria, intentan limpiar y salir, es decir, fallan con elegancia. No recuerdo la última vez que vi que uno realmente intentaba recuperarse y continuar operando normalmente.¿Es "Memoria insuficiente" un error recuperable?

Tanto procesamiento se basa en poder asignar con éxito la memoria, especialmente en los lenguajes recogidos basura, parece que los errores de memoria se deben clasificar como no recuperables. (Los errores no recuperables incluyen cosas como desbordamientos de pila.)

¿Cuál es el argumento convincente para hacerlo un error recuperable?

+0

Disculpa si el comentario anterior fue grosero. Pero, por ejemplo, las aplicaciones de la GUI de Java manejan bastante bien OutOfMemoryError (no soy un gran admirador de Java, solo tengo en cuenta mi experiencia): finalizado es, p. solo la solicitud se originó a partir de la acción de un solo usuario. – KarolDepka

+0

También a veces es bueno dejar que un solo hilo muera, pero deje que el resto del programa se ejecute, lo que a veces ocurre de forma natural. – KarolDepka

+0

También a veces se puede contener la falla para sabotear solo el manejo de eventos únicos (como en, por ejemplo, el ciclo/subproceso de envío de eventos GUI). – KarolDepka

Respuesta

1

En el caso general, no es recuperable.

Sin embargo, si su sistema incluye alguna forma de almacenamiento en caché dinámico, un controlador de memoria insuficiente a menudo puede volcar los elementos más antiguos en la memoria caché (o incluso la memoria caché completa).

Por supuesto, debe asegurarse de que el proceso de "volcado" no requiere nuevas asignaciones de memoria :) Además, puede ser complicado recuperar la asignación específica que falló, a menos que pueda conectar su código de volcado de memoria caché directamente en el nivel de asignador, para que la falla no se propague a la persona que llama.

+0

¿No sería esto más general y mejor manejado por ¿Puede marcar algunas asignaciones como "débiles", lo que significa que el asignador puede liberarlas si necesita más memoria? –

+0

posiblemente, aunque es probable que necesite otro nombre, ya que generalmente "débil" se usa para referencias en lugar de asignaciones, y sobrecargarlo de esta manera probablemente lleve a confusión. Y yendo con su enfoque no podría ser tan selectivo como la limpieza de caché (u otros manejadores) –

35

Realmente depende de lo que estés construyendo.

No es completamente irrazonable que un servidor web falle un par de solicitud/respuesta, pero luego continúe con las solicitudes. Sin embargo, tendría que estar seguro de que la única falla no tenía efectos perjudiciales en el estado global, sería un poco complicado. Dado que una falla causa una excepción en la mayoría de los entornos administrados (por ejemplo, .NET y Java), sospecho que si la excepción se maneja en "código de usuario" sería recuperable para futuras solicitudes, por ej. si una solicitud intenta asignar 10 GB de memoria y falla, eso no debería dañar el resto del sistema. Sin embargo, si el sistema se queda sin memoria mientras intenta entregar la solicitud al código de usuario, ese tipo de cosas podrían ser más desagradables.

+39

Whoa ... Jon Skeet respondiendo una pregunta de Walter Bright. Acabo de experimentar un escalofrío en la columna vertebral (o tal vez porque estaba a 62 ° F aquí). –

0

Esta es una pregunta difícil. A primera vista, parece que no tener más memoria significa "falta de suerte", pero también debes ver que uno puede deshacerse de muchas cosas relacionadas con la memoria si uno realmente insiste. Simplemente tomemos la función de otra manera, strtok, que por un lado no tiene problemas con la memoria. A continuación, tome como contrapartida g_string_split de la biblioteca Glib, que depende en gran medida de la asignación de memoria como casi todo en programas basados ​​en glib o GObject. Uno puede decir definitivamente en lenguajes más dinámicos que la asignación de memoria es mucho más utilizada que en lenguajes más inflexibles, especialmente C. Pero veamos las alternativas. Si acaba el programa si se queda sin memoria, incluso el código desarrollado cuidadosamente puede dejar de funcionar. Pero si tiene un error recuperable, puede hacer algo al respecto. Entonces, el argumento, haciéndolo recuperable significa que uno puede elegir "manejar" esa situación de manera diferente (por ejemplo, dejando de lado un bloque de memoria para emergencias, o degradación a un programa menos extensivo en memoria).

Así que la razón más convincente es. Si proporciona una manera de recuperar uno puede probar el recoverying, si no tiene la opción todo depende de conseguir siempre la memoria suficiente ...

Saludos

5

Creo que como muchas otras cosas, es un costo/análisis de beneficios. Usted puede programa en intento de recuperación de una falla de malloc() - aunque puede ser difícil (es mejor que su controlador no caiga en la misma falta de memoria con la que debe lidiar).

Ya ha notado que el caso más común es limpiar y fallar con elegancia.En ese caso, se ha decidido que el costo de abortar correctamente es menor que la combinación del costo de desarrollo y el costo de rendimiento en la recuperación.

Estoy seguro de que puedes pensar en tus propios ejemplos de situaciones donde terminar el programa es una opción muy costosa (máquina de soporte vital, control de nave espacial, cálculo financiero de larga duración y crítico), aunque el primero La línea de defensa es, por supuesto, para garantizar que el programa tenga un uso de memoria predecible y que el entorno pueda proporcionar eso.

+1

Si es impensable terminar el programa debido a errores de falta de memoria, entonces usted tiene un problema de diseño muy serio en sus manos, probablemente necesitando una solución personalizada (como asignar estáticamente todos los datos o asignarla de antemano). –

+0

Bueno, sí, pero hay grados de impensable, y hay grados de esfuerzo que puede poner en las estrategias de recuperación. Estoy seguro de que esta es una consideración muy común cuando se desarrolla para consolas de juegos, por ejemplo. – slim

+0

Una estrategia trivial que podría ser suficiente para algunas aplicaciones: void * my_malloc (size_t nbytes) {for (int i = 0; i slim

17

En una biblioteca, quiere copiar un archivo de manera eficiente. Cuando haces eso, generalmente encontrarás que copiar usando una pequeña cantidad de trozos grandes es mucho más efectivo que copiar muchos más pequeños (por ejemplo, es más rápido copiar un archivo de 15MB copiando 15 trozos de 1MB que copiar 15,000 Trozos de 1K).

Pero el código funciona con cualquier tamaño de porción. Entonces, si bien puede ser más rápido con fragmentos de 1MB, si diseña para un sistema donde se copian muchos archivos, puede ser conveniente capturar OutOfMemoryError y reducir el tamaño del fragmento hasta que tenga éxito.

Otro lugar es una memoria caché de objetos almacenados en una base de datos. Desea mantener tantos objetos en la memoria caché como sea posible pero no quiere interferir con el resto de la aplicación. Dado que estos objetos se pueden volver a crear, es una manera inteligente de conservar la memoria para adjuntar el caché a un manejador sin memoria para eliminar las entradas hasta que el resto de la aplicación tenga suficiente espacio para respirar, nuevamente.

Por último, para la manipulación de imágenes, que desea cargar como parte de la imagen en la memoria como sea posible. Una vez más, un controlador OOM le permite implementar eso sin saber de antemano cuánta memoria el usuario o sistema operativo le otorgará a su código.

[EDIT] Nota que trabajo bajo el supuesto aquí que has dado la aplicación de una cantidad fija de memoria y esta cantidad es menor que el espacio total de memoria disponible con exclusión de intercambio. Si puede asignar tanta memoria que parte de ella tiene que ser intercambiada, muchos de mis comentarios ya no tienen sentido.

+7

En un sistema con memoria virtual, investigar cuánto puede asignar significa que va a asignar memoria paginada al disco, lo que es una pesimización para un búfer de disco. –

+1

Punto de datos en su defensa: uClibc tiene un búfer interno estático de 8 bytes más o menos para E/S de archivos cuando no hay más memoria asignada dinámicamente. –

5

Estoy trabajando en un sistema que asigna memoria caché de IO para aumentar el rendimiento. Luego, al detectar OOM, se lleva algo de vuelta, de modo que la lógica de negocios pueda continuar, incluso si eso significa menos caché de IO y un rendimiento de escritura ligeramente menor.

También trabajé con aplicaciones embebidas de Java que intentaban administrar OOM forzando la recolección de basura, liberando opcionalmente algunos objetos no críticos, como datos precargados o en caché.

Los principales problemas con el manejo OOM son:

1) ser capaz de volver a tratar en el lugar donde ocurrió o ser capaz de hacer retroceder y volver a tratar desde un punto más alto. La mayoría de los programas contemporáneos confían demasiado en el lenguaje para lanzar y no logran realmente dónde terminan y cómo volver a intentar la operación. Por lo general, se perderá el contexto de la operación, si no fue diseñado para ser preservado

2) ser capaz de liberar algo de memoria en realidad. Esto significa un tipo de administrador de recursos que sabe qué objetos son críticos y cuáles no, y el sistema puede volver a solicitar los objetos liberados cuando más tarde se vuelvan críticos

Otro tema importante es poder rodar volver sin desencadenar otra situación OOM. Esto es algo que es difícil de controlar en idiomas de nivel superior.

Además, el sistema operativo subyacente debe comportarse predecible con respecto a OOM. Linux, por ejemplo, no lo hará, si la sobrecomisión de la memoria está habilitada. Muchos sistemas habilitados para el intercambio morirán antes que reportar el OOM a la aplicación ofensiva.

Y existe el caso cuando no es su proceso el que creó la situación, por lo que liberar memoria no ayuda si el proceso ofensivo sigue produciendo una fuga.

Debido a todo esto, a menudo son los sistemas grandes e integrados que emplean estas técnicas, ya que tienen el control sobre el sistema operativo y la memoria para habilitarlos, y la disciplina/motivación para implementarlos.

+0

¿Entonces ve que recuperarse de OOM es algo que haría con un método de asignación de memoria personalizado, no con una biblioteca estándar? –

+0

también puede hacerlo con el método estándar, si sabe qué liberar y puede hacerlo sin requerir memoria nueva. Lo hicimos con el administrador de memoria Java estándar con cierto éxito. –

4

Es recuperable solo si la atrapa y maneja correctamente.

En los mismos casos, por ejemplo, una solicitud intentó asignar una gran cantidad de memoria. Es bastante predecible y puedes manejarlo muy bien.

Sin embargo, en muchos casos en aplicaciones de subprocesos múltiples, OOE también puede ocurrir en la cadena de fondo (incluso creada por sistema/biblioteca de terceros). Es casi imposible de predecir y es posible que no pueda recuperar el estado de todos sus hilos.

1

Depende de lo que quiera decir con la falta de memoria.

Cuando malloc() falla en la mayoría de los sistemas, es porque se ha agotado el espacio de direcciones.

Si la mayoría de esa memoria está ocupada por la caché o por regiones mmap'd, es posible que pueda reclamar parte de ella liberando su caché o anulándolo. Sin embargo, esto realmente requiere que sepas para qué estás usando esa memoria y, como habrás notado, la mayoría de los programas no lo hacen o no hace la diferencia.

Si utilizó setrlimit() en usted (para protegerse contra ataques imprevistos, tal vez, o tal vez root se lo hizo), puede relajar el límite en su controlador de errores. Hago esto con mucha frecuencia, después de avisar al usuario si es posible y registrar el evento.

Por otro lado, el desbordamiento de la pila de captura es un poco más difícil y no es portátil. Escribí una solución posixish para ECL, y describí una implementación de Windows, si vas por esta ruta. Fue revisado en ECL hace unos meses, pero puedo desenterrar los parches originales si está interesado.

3

No. Un error de falta de memoria del GC generalmente no debería ser recuperable dentro del hilo actual. (La creación y terminación del hilo recuperable (usuario o kernel) debería soportarse)

En cuanto a los ejemplos del contador: Actualmente estoy trabajando en un proyecto de lenguaje de programación D que utiliza la plataforma CUDA de NVIDIA para computación GPU. En lugar de administrar manualmente la memoria GPU, he creado objetos proxy para aprovechar el GC de D's. Entonces, cuando la GPU devuelve un error de falta de memoria, ejecuto una recopilación completa y solo genero una excepción si falla por segunda vez. Pero, esto no es realmente un ejemplo de recuperación de memoria insuficiente, es más una integración de GC. Los otros ejemplos de recuperación (cachés, listas libres, apilamientos/hashes sin contracción automática, etc.) son todas estructuras que tienen sus propios métodos de recopilación/compactación de memoria que están separados del GC y tienden a no ser locales para la asignación. función. Así que la gente podría implementar algo como lo siguiente:

T new2(T)(lazy T old_new) { 
    T obj; 
    try{ 
     obj = old_new; 
    }catch(OutOfMemoryException oome) { 
     foreach(compact; Global_List_Of_Delegates_From_Compatible_Objects) 
      compact(); 
     obj = old_new; 
    } 
    return obj; 
} 

¿Qué es un argumento decente para añadir soporte para registrar/anular el registro de auto-recogida/compactar objetos a los recolectores de basura en general.

9

Los usuarios de MATLAB se quedan sin memoria todo el tiempo cuando realizan operaciones aritméticas con arreglos grandes.Por ejemplo, si la variable x cabe en la memoria y ejecutan "x + 1", MATLAB asigna espacio para el resultado y luego lo llena. Si la asignación falla los errores de MATLAB y el usuario puede intentar algo diferente. Sería un desastre si MATLAB saliera cada vez que surgiera este caso de uso.

0

Me está desconcertando ahora.

En el trabajo, tenemos un conjunto de aplicaciones trabajando juntas, y la memoria se está agotando. Si bien el problema es hacer que el paquete de aplicaciones sea de 64 bits (y así poder trabajar más allá de los 2 límites de Go que tenemos en un sistema operativo Win32 normal) y/o reducir el uso de memoria, este problema de "Cómo recuperarse de un OOM "no me abandonará la cabeza.

Por supuesto, no tengo solución, pero todavía juego buscando uno para C++ (debido a RAII y excepciones, principalmente). Quizás un proceso que supuestamente se debe recuperar correctamente debe desglosar su procesamiento en tareas atómicas/reversibles (es decir, utilizando solo funciones/métodos que otorguen garantía de excepciones fuertes/nulas), con un "búfer/reserva de memoria" reservado para recuperar propósitos.

En caso de que una de las tareas falle, el C++ bad_alloc desenrollaría la pila, liberaría algo de memoria de pila/montón a través de RAII. La función de recuperación se recuperaría tanto como fuera posible (guardando los datos iniciales de la tarea en el disco, para usarla en un intento posterior), y tal vez registrara los datos de la tarea para una prueba posterior.

Creo que el uso de C++ strong/nothrow guanrantees puede ayudar a que un proceso sobreviva en condiciones de baja disponibilidad de memoria, incluso si sería un intercambio de memoria (es decir, lento, algo no correspondido, etc.), pero Por supuesto, esto es solo teoría. Solo necesito ser más inteligente sobre el tema antes de intentar simular esto (es decir, crear un programa C++, con un asignador nuevo/eliminar personalizado con memoria limitada, y luego intentar hacer algún trabajo bajo esas condiciones estresantes).

Bueno ...

7

OOM debe ser recuperable debido a la parada no es la única estrategia para recuperarse de OOM.

En realidad, existe una solución bastante estándar para el problema de OOM en el nivel de la aplicación. Como parte del diseño de la aplicación, determine una cantidad mínima segura de memoria necesaria para recuperarse de una condición de falta de memoria. (Por ejemplo, la memoria requerida para guardar documentos automáticamente, abrir cuadros de diálogo de advertencia, cerrar datos de cierre).

Al inicio de su aplicación o al comienzo de un bloque crítico, asigne previamente esa cantidad de memoria. Si detecta una condición de falta de memoria, libere la memoria de protección y realice la recuperación. La estrategia aún puede fallar, pero en general da un gran golpe por el dinero.

Tenga en cuenta que la aplicación no necesita detenerse. Puede mostrar un diálogo modal hasta que se haya resuelto la condición OOM.

No estoy 100% seguro pero estoy bastante seguro de que 'Code Complete' (lectura obligatoria para cualquier ingeniero de software respetable) lo cubre.

P.S. Puede ampliar su marco de aplicaciones para ayudar con esta estrategia, pero no implemente dicha política en una biblioteca (las buenas bibliotecas no toman decisiones globales sin un consentimiento de aplicaciones)

+0

Esto se menciona en Code Complete. La técnica se llama "paracaídas" si no recuerdo mal. –

+0

Desafortunadamente, no se puede hacer de manera confiable en Java, porque a la JVM se le permite lanzar OOM en * cualquier momento, no solo cuando tiene un 'nuevo'. Por lo tanto, si atrapa un OOM, * podría * haber sido lanzado en un punto que ha dejado su programa en un estado incoherente. Consulte http://stackoverflow.com/questions/8728866/no-throw-virtualmachineerror-guarantees – Raedwald

0

Especialmente en entornos recolectados de basura, es probable que Si detecta el error de OutOfMemory en un nivel alto de la aplicación, muchas cosas han salido del alcance y se pueden recuperar para devolverle la memoria.

En el caso de asignaciones excesivas únicas, la aplicación puede continuar funcionando sin problemas. Por supuesto, si tiene una fuga gradual de memoria, se encontrará nuevamente con el problema (más pronto que tarde), pero aún así es una buena idea dar a la aplicación la oportunidad de bajar con elegancia, guardar los cambios no guardados en el caso de una aplicación GUI, etc.

0

Sí, OOM es recuperable. Como ejemplo extremo, los sistemas operativos Unix y Windows se recuperan bastante bien de las condiciones OOM, la mayoría de las veces. Las aplicaciones fallan, pero el sistema operativo sobrevive (suponiendo que haya suficiente memoria para que el sistema operativo se inicie correctamente en primer lugar).

única Cito este ejemplo para demostrar que se puede hacer.

El problema de tratar con OOM es realmente depende de su programa y el medio ambiente.

Por ejemplo, en muchos casos, el lugar donde ocurre el OOM probablemente NO es el mejor lugar para recuperarse realmente de un estado OOM.

Ahora, un asignador personalizado podría funcionar como un punto central dentro del código que puede manejar un OOM. El asignador de Java realizará un GC completo antes de lanzar una excepción OOM.

Cuanto más "consciente de la aplicación" sea su asignador, mejor será como controlador central y agente de recuperación para OOM. Usando Java de nuevo, su asignador no es particularmente consciente de las aplicaciones.

Esto es donde algo como Java es fácilmente frustrante. No puede anular el asignador. Por lo tanto, aunque podría atrapar las excepciones de OOM en su propio código, no hay nada que diga que alguna biblioteca que esté utilizando atrape correctamente, o incluso que muestre correctamente una excepción de OOM. Es trivial crear una clase que se arruine para siempre con una excepción OOM, ya que algunos objetos se establecen en nulos y "eso nunca sucede", y nunca se pueden recuperar.

Entonces, sí, OOM es recuperable, pero puede ser MUY difícil, especialmente en entornos modernos como Java y su gran cantidad de bibliotecas de terceros de diversa calidad.

0

La falta de memoria normalmente significa que debe abandonar lo que estaba haciendo. Sin embargo, si tiene cuidado con la limpieza, puede dejar el programa en funcionamiento y responder a otras solicitudes. Es mejor tener un programa que diga "Lo siento, no hay suficiente memoria para hacer" que decir "Lo siento, sin memoria, apago".

0

La falta de memoria puede deberse al agotamiento de la memoria o al tratar de asignar un bloque irracionalmente grande (como un concierto). En los casos de "agotamiento", la falta de memoria es global para el sistema y generalmente afecta a otras aplicaciones y servicios del sistema, y ​​todo el sistema puede volverse inestable, por lo que es aconsejable olvidarse y reiniciarse. En los casos de "bloque irrazonablemente grande", no hay escasez y es seguro continuar. El problema es que no puede detectar automáticamente en qué caso se encuentra. Por lo tanto, es más seguro hacer que el error no sea recuperable y encontrar una solución alternativa para cada caso que encuentre este error: haga que su programa use menos memoria o en algunos casos solo corrija errores en el código que invoca la asignación de memoria.

0

Ya hay muchas buenas respuestas aquí. Pero me gustaría contribuir con otra perspectiva.

El agotamiento de casi cualquier recurso reutilizable debe ser recuperable en general. El razonamiento es que cada parte del programa es básicamente un subprograma. El hecho de que un submarino no pueda completar su fin en este mismo momento, no significa que todo el estado del programa sea basura. El hecho de que el estacionamiento esté lleno de autos no significa que descargues tu auto.O esperas un rato para que un stand sea gratuito o entras en una tienda más lejos para comprar tus cookies.

En la mayoría de los casos hay una manera alternativa. Hacer que un error sea irrecuperable, elimina de manera efectiva muchas opciones, y ninguno de nosotros quiere que nadie decida por nosotros qué podemos y qué no podemos hacer.

Lo mismo se aplica al espacio en disco. Es realmente el mismo razonamiento. Y, contrariamente a su insinuación sobre el desbordamiento de la pila es irrecuperable, diría que es una limitación arbitraria. No hay una buena razón para que no se pueda lanzar una excepción (apareciendo muchos marcos) y luego usar otro enfoque menos eficiente para hacer el trabajo.

Mis dos centavos :-)

0

Si está realmente fuera de la memoria que están condenados, ya que no pudo nada más.

Si se ha quedado sin memoria, pero algo así como un recolector de basura puede entrar en acción y liberar algo de memoria, aún no está muerto.

El otro problema es la fragmentación. Aunque es posible que no te quedes sin memoria (fragmentada), es posible que aún no puedas asignar la gran cantidad que quieres tener.

-1

tengo esto:

void *smalloc(size_t size) { 
    void *mem = null; 
    for(;;) { 
    mem = malloc(size); 
    if(mem == NULL) { 
    sleep(1); 
    } else 
    break; 
    } 
    return mem; 
} 

que ha salvado un sistema unas cuantas veces ya. El hecho de que se haya quedado sin memoria ahora no significa que alguna otra parte del sistema u otros procesos que se ejecutan en el sistema tengan algo de memoria que devolverán pronto. Es mejor que tengas mucho cuidado antes de intentar tales trucos, y tener todo el control sobre cada memoria que asignas en tu programa.

+0

¿Qué sucede si otro proceso está utilizando toda la memoria y no la devuelve al sistema operativo? entonces estarás sentado en el circuito para siempre, sin saber nada de lo que está pasando. ¿No sería mejor si algo pudiera registrarse? – Matt

+1

Claro. Lo anterior es solo un ejemplo, puede registrar algo, puede intentar solo 20 veces en lugar de un bucle infinito, etc. – nos

0

Sé que pidió argumentos, pero solo puedo ver argumentos en contra.

No veo de todos modos para lograr esto en una aplicación multiproceso. ¿Cómo se sabe qué hilo es realmente responsable del error de falta de memoria? Un hilo podría asignar nueva memoria constantemente y tener gc-roots al 99% del montón, pero la primera asignación que falla ocurre en otro hilo.

Un ejemplo práctico: cada vez que se produce un OutOfMemoryError en nuestra aplicación Java (ejecutándose en un servidor JBoss), no es como si un hilo fallece y el resto del servidor sigue ejecutándose: no, hay varias OOME, que matan varios hilos (algunos de los cuales son hilos internos de JBoss). No veo lo que podría hacer como programador para recuperarme de eso, o incluso lo que JBoss podría hacer para recuperarse de eso. De hecho, ni siquiera estoy seguro de que PUEDA: el javadoc for VirtualMachineError sugiere que la JVM puede estar "rota" después de que se arroje un error de este tipo. Pero tal vez la pregunta estaba más dirigida al diseño del lenguaje.

0

uClibc tiene un búfer interno estático de 8 bytes más o menos para E/S de archivo cuando no hay más memoria asignada dinámicamente.

0

¿Cuál es el argumento convincente para hacerlo un error recuperable?

En Java, un argumento convincente para no por lo que es un error recuperable se debe a que Java permite OOM a ser señalado en cualquier momento, incluso en momentos en los que el resultado podría ser su programa entra en un estado incoherente.La recuperación confiable de un OOM es por lo tanto imposible; Si detecta la excepción OOM, no puede confiar en cualquiera de su estado de programa. Ver No-throw VirtualMachineError guarantees

1

La pregunta está etiquetada "language-agnostic", pero es difícil de responder sin tener en cuenta el idioma y/o el sistema subyacente. (Veo varias hadns toher

Si la asignación de memoria está implícito, con ningún mecanismo para detectar si una asignación dada tuvo éxito o no, entonces recuperarse de una condición de fuera de la memoria puede ser difícil o imposible.

Para Por ejemplo, si llama a una función que intenta asignar una matriz enorme, la mayoría de los lenguajes simplemente no definen el comportamiento si no se puede asignar la matriz. (En Ada esto genera una excepción Storage_Error, al menos en principio, y debería ser posible manejar eso.)

Por otro lado, si tiene un mecanismo que intenta asignar memoria y es capaz de informar una falla al hacerlo (como C malloc() o C++ new), entonces sí, ciertamente es posible recuperarse de esa falla. En al menos los casos de malloc() y new, una asignación fallida no hace otra cosa que informar el error (no corrompe ninguna estructura de datos interna, por ejemplo).

Si tiene sentido intentar recuperar depende de la aplicación. Si la aplicación simplemente no puede tener éxito después de una falla de asignación, entonces debe hacer cualquier limpieza que pueda y finalizar. Pero si la falla de asignación simplemente significa que una tarea en particular no se puede realizar, o si la tarea aún se puede realizar más lentamente con menos memoria, entonces tiene sentido continuar con la operación.

Un ejemplo concreto: Supongamos que estoy usando un editor de texto. Si trato de realizar alguna operación dentro del editor que requiera mucha memoria, y esa operación no se puede realizar, quiero que el editor me diga que no puede hacer lo que le pedí al y me permite seguir editando. Terminar sin guardar mi trabajo sería una respuesta inaceptable. Guardar mi trabajo y terminar sería mejor, pero aún así es innecesariamente hostil para el usuario.

Cuestiones relacionadas