2011-04-05 9 views
6

Los programas C++ pueden definir y establecer un new_handler() al que se debe llamar desde funciones de asignación de memoria como operator new() si es imposible asignar la memoria solicitada.¿Para qué se puede usar "new_handler" en C++ además de la recolección de basura?

Un uso de un new_handler() personalizado es dealing with C++ implementations that don't throw an exception on allocation failure. Otro uso es iniciar la recolección de basura en los sistemas que implementan la recolección de basura.

¿Qué otros usos de la costumbre new_handler() hay?

Respuesta

7

De manera similar a la aplicación de recolección de elementos no utilizados, puede usar el nuevo controlador para liberar los datos en caché que pueda tener.

Digamos que está almacenando en caché algunos datos de recursos leídos del disco o los resultados intermedios de algunos cálculos. Se trata de datos que puede recrear en cualquier momento, de modo que cuando se llama al nuevo controlador (lo que significa que se ha agotado el montón), puede liberar la memoria para los datos en caché y luego regresar desde el nuevo controlador. Con suerte, new ahora podrá realizar la asignación.

En muchos casos, la memoria virtual puede servir para el mismo propósito: simplemente puede dejar que sus datos en caché se intercambien en el disco, si tiene suficiente espacio de direcciones virtuales. En sistemas de 32 bits, este ya no es el caso, por lo que el nuevo controlador es una opción interesante. Muchos sistemas integrados enfrentarán restricciones similares.

6

En la mayoría de los servidores de los que he trabajado, el new_handler liberados un bloque preasignados (para que los futuros nuevos de no fallaría) antes de ingresar un mensaje (el registrador se utiliza la memoria dinámica) y abortar. Esto aseguró que el error de falta de memoria se registró correctamente (en lugar de que el proceso simplemente "desaparezca", con un mensaje de error al cerr, que se conectó a /dev/null).

En aplicaciones como editores, etc., es posible que derrame partes de algunos almacenamientos intermedios en el disco, luego continúe; si el new_handler regresa, se supone que el operador nuevo debe volver a intentar la asignación , y si new_handler ha liberado suficiente memoria, la asignación puede tener éxito (y si no, se llamará nuevamente al new_handler , tal vez gratis hasta más).

1

Nunca lo he usado para nada - demasiados sistemas operativos otorgarán memoria virtual y SIGSEGV o similar si no pueden proporcionarlo más tarde, por lo que no es una buena idea hacer un sistema que dependa de ser tolerante al agotamiento de la memoria : a menudo está fuera de las manos de C++. Sin embargo, si se desarrolló para un sistema en el que se puede/se debe confiar, puedo imaginar fácilmente una situación en la que algunos datos en tiempo real se estaban transfiriendo a una cola en su proceso, y se estaba procesando y escribiendo/enviando resultados. lo más rápido que pueda (por ejemplo, video de transmisión de video por hardware para recompresión a disco/red). Si llegas a la etapa en la que no puedes almacenar más, simplemente debes dejar caer algo, pero ¿cómo sabrías cuándo se puso tan mal? Establecer un límite arbitrario sería una tontería, especialmente si su software era para un entorno/caja incrustado que solo existía para realizar esta tarea. Y, probablemente no deberías usar una función como esta casualmente en un sistema con cualquier tipo de memoria de intercambio basada en disco duro, como si ya estuvieras en intercambio, las tasas de rendimiento serían miserables para siempre. Pero, más allá de las advertencias, podría ser útil dejar caer paquetes por un tiempo hasta que se pongan al día. Quizás dejar caer cada enésimo fotograma a través del búfer en cola sería menos visible que dejar caer un pedazo en la parte posterior o frontal de la cola. Lo que sea, descartar datos de la cola podría ser un uso razonable del nivel de la aplicación (a diferencia del subsistema intra-memoria) para algo como esto ...

Cuestiones relacionadas