new bidimensional array c++ new-operator dynamic-memory-allocation

bidimensional - new int c++



Comprender el comportamiento del nuevo manejador. (3)

No volver

Simplemente intentó todo lo que pudo y no pudo hacer que haya más memoria disponible. Llama a exit() o abort() y finaliza el proceso.

Esto puede ser usado como una estrategia rápida de falla. Si la memoria no tiene suficiente en un sistema y se sabe que algunos procesos no son necesarios (p. Ej., Los trabajadores secundarios), abort() liberará la memoria para otros procesos y es la forma más rápida de deshacerse de los procesos.

lanzar una excepción

Lanzar bad_alloc significa que el asignador no puede liberar ninguna memoria y si la aplicación puede recuperarse de algún modo. Personalmente, no me importa capturar realmente bad_alloc ya que no debería ocurrir o no puedo hacer nada al respecto.

Esto podría usarse si está utilizando compiladores antiguos que devuelven nullptr al salir de la memoria para forzarlos a lanzar. Sin embargo, es cuestionable si esto funcionaría.

Desinstalar el nuevo controlador

Mirando el libro llamando a set_new_handler(nullptr); debe desinstalar el nuevo controlador. Según Scott Meyer, esto debería llevar a que el operator new lance la excepción bad_alloc . Esto debería ser idéntico a lanzar la excepción tú mismo.

Instalar un nuevo controlador diferente

Dado que se llama al new_handler hasta que se resuelve el error de asignación (es decir, no es resuelto por el operator new ) si una implementación siempre que new_handler no sea capaz de resolver el problema, debe propagar la condición a otra capa.

Si yo mismo instalara un new_handler , mantendría una referencia (consulte también: get_new_handler() ) al new_handler anterior para intercambiarlo de nuevo cuando mi algoritmo esté fallando.

Hacer más memoria disponible

El supuesto aquí es que la aplicación instaló el new_handler sí. El autor de new_handler tiene la oportunidad de realizar una introspección o modificar la memoria asignada. Así que el programador ha instalado el new_handler porque sabe que hay algo de memoria para liberar. En caso de que todo salga mal, hay una estrategia para recuperarse de este fracaso.

Una lista incompleta de lo que podría estar pasando (adivinanzas parciales):

  • su sistema operativo le permite llamar al asesino sin memoria manualmente (para liberar memoria)
  • Si está utilizando el recolector de basura Boehm, podría llamar a GC_gcollect(); Para forzar la recolección de basura.
  • Usted ha reservado algo de memoria que usted comienza a usar ahora.
  • manualmente llama a eliminar a objetos conocidos que no se pueden reparar (cachés).
  • tiene un intérprete ejecutándose como Perl, Python o Mono y llama a su recolector de basura para decirles que tiene poca condición de memoria (o ellos mismos instalan el nuevo controlador en sus rutinas init() ).

Implementación

Aquí está la implementación de libstdc++ .

Estoy leyendo Effective C ++ 55 de Scott Meyers y tengo una pregunta del artículo 49:

Cuando el operator new no puede cumplir una solicitud de memoria, llama a la función de nuevo controlador repetidamente hasta que pueda encontrar suficiente memoria.

Una función newhandler bien diseñada debe realizar una de las siguientes acciones:

  • Hacer más memoria disponible.
  • Instalar un nuevo controlador nuevo.
  • Desinstalar el nuevo controlador
  • Lanzar una excepción
  • No volver

Cuando la new no puede asignar memoria, significa que no hay suficiente memoria, y la pregunta es cómo y de dónde puede asignar más memoria el newhandler.

¿Puedes explicar todos estos pasos?


Depende de la implementación. Puedo decirte la forma en que normalmente lo hago:

1) El nuevo controlador asigna una gran cantidad de memoria al inicio como reserva.

2) Cuando las asignaciones ordinarias fallan, el nuevo controlador se sumerge en su reserva.

3) El código que controla la administración de carga puede conectar el sistema de administración de memoria y determinar cuándo se ha reducido a su reserva. En general, reacciona recortando cachés y eliminando la carga.

4) El administrador de memoria intenta recargar sus reservas a medida que se libera la memoria.

5) Cuando se restaura la reserva, se notifica a los ganchos que pueden aumentar los cachés y / o reanudar la aceptación de carga adicional.

6) Cuando las reservas se vuelven bajas, fallan las asignaciones que pueden fallar (generalmente grandes asignaciones). Todo el código debe manejar sanamente el fallo de las grandes asignaciones.

7) Si se agotan las reservas, se bloquean las asignaciones que no pueden fallar (generalmente asignaciones pequeñas).

8) Si la condición de bloqueo persiste o las asignaciones grandes continúan fallando y la reserva no se puede restaurar, se activa una terminación anormal.


Puede descartar datos que no son realmente necesarios. Por ejemplo, photoshop almacena en caché la imagen de visualización en varias escalas y mantiene todo lo que puede. Así es como sabe cuánto puede salirse con la suya.