.net - tube - robot de platon internet
¿Qué tan importante es disponer de una fuente, realmente? (6)
¿Por qué no lo desecharías una vez que hayas terminado? El hecho de que tengamos barrenderos no significa que debamos rodear las calles. Sin embargo, en el ejemplo dado, si la fuente es necesaria para la vida útil del objeto, elimine la fuente en la disposición de ese objeto. Hay muchas cosas que también simplificarían mi código, pero eso no justifica esos cambios; a veces hay cosas que debes hacer, aunque sea un dolor.
Siempre es una buena idea poner en orden después de ti mismo. Cuando ya no necesite algo, deséchelo. De esa manera, puede evitar condiciones de carrera desagradables, excepciones sin memoria, problemas de dibujo y largas recolecciones de basura que requieren un uso intensivo del procesador.
Me parece que es una buena práctica deshacerse de los objetos desechables si ya no los necesita, a menos que haya una razón justificada para no hacerlo (por ejemplo, si no es el propietario del objeto). Es más difícil rastrear la causa raíz de un problema que codificar defensivamente desde el principio.
Con respecto a la fuente, MSDN dice :
Siempre llame a Dispose antes de publicar su última referencia a la Fuente. De lo contrario, los recursos que está utilizando no se liberarán hasta que el recolector de basura llame al método Finalizar del objeto Fuente.
No dice cuáles son los recursos, pero el hecho de que expresen explícitamente que esto debe hacerse implícitamente agrega importancia a la llamada Dispose.
Soy consciente de que la mejor práctica es llamar a Dispose en cualquier objeto que implemente IDisposable, especialmente los objetos que encierran recursos finitos, como identificadores de archivos, sockets, identificadores GDI, etc.
Pero me estoy topando con un caso en el que tengo un objeto que tiene una Fuente, y tendría que revisar IDisposable a través de varias capas de objetos, y revisar muchos usos, para asegurarme de que siempre deseche la Fuente. Y me pregunto si vale la pena la complejidad.
Una cosa sería si Font envolviera un HFONT, porque los recursos GDI son globales para el sistema. Pero la fuente no envuelve un identificador de GDI; es GDI +, que es un sistema completamente separado y, según tengo entendido, es un proceso local, no un sistema global como el GDI. Y a diferencia de la Imagen, la Fuente nunca se aferra a los recursos del sistema de archivos (que yo sepa, de todos modos).
Entonces, mi pregunta es: ¿Cuál es el costo real de dejar que una fuente se recolecte?
Sé que tomaría un pequeño golpe para el finalizador, pero si el número de fuentes "filtradas" es pequeño (por ejemplo, media docena), ese golpe honestamente no se notaría. Aparte del finalizador, esto no parece ser muy diferente de asignar una matriz de tamaño mediano y dejar que el GC lo limpie, es solo memoria.
¿Hay costos que no conozco al permitir que una fuente se gane?
¿Qué tan importante es deshacerse de algo , de verdad? En mi humilde opinión cuando empiezas a hacer este tipo de preguntas, parece que tienes un problema de diseño en tu código. Siempre debe deshacerse de las cosas que ya no necesita, lo que se denomina programación responsable.
Posibles soluciones a su problema:
No pase objetos como las
Fonts
. Implemente la lógica de uso de fuentes en un lugar (una clase), agregue la Fuente como un campo de esa clase e implementeIDisposable
para esa clase.Implemente una clase de caché de fuentes : en lugar de crear nuevos objetos de
Font
con elnew
operador en todo su código, use esta clase para obtener laFont
deseada. La clase puede tener la lógica para reutilizar las fuentes existentes, si es posible. O para mantener las últimas 10 fuentes en la memoria y desechar las demás. ImplementeIDisposable
para el caché, que se llamará una vez en el ciclo de vida de su aplicación.
El problema es que la recolección de basura solo ocurre cuando hay presión de memoria. A menudo, los manejadores no administrados están más restringidos que la memoria, por lo que puede quedarse sin manejadores antes de que ocurra GC, lo que provoca errores.
Pero para una o dos instancias de Font
, no te perjudicará demasiado.
Un problema mayor es que algunos de los objetos se comparten y no deben (o no pueden) ser eliminados prematuramente ...
Los finalizadores están integrados en clases específicamente porque la limpieza es necesaria. Independientemente de si tiene una gran cantidad de objetos para limpiar, es una buena práctica limpiarlos.
El GC fue construido para tener una pseudo mente propia. Al desechar correctamente sus objetos, está permitiendo que el GC haga lo que fue hecho para hacer.
Sin embargo, si está creando una gran cantidad de objetos de fuente y desechándolos todos, puede ser beneficioso llamar al GC en la generación apropiada (probablemente la generación 0) cada cierto tiempo para iniciar una limpieza de GC, según los tipos. De otros objetos que estás creando en gran número. Tu objetivo debe ser evitar que los objetos que sabes que no estás utilizando durante mucho tiempo se conviertan en generaciones mayores. Esto mantiene el trabajo del GC magro y malo.
Solo usa tu mejor juicio y estarás bien. Pero, de hecho, elimine cualquier objeto con un finalizador como práctica habitual.
Respuesta simple: si solo son unos pocos, entonces no. Si es mucho, entonces sí. Si su aplicación ya está haciendo hincapié en el recolector de basura, entonces sí. Usaría perfmon para ver la cantidad de objetos que se sientan, y la cantidad que se promueve a generaciones más altas, y luego decidir.
Tengo al menos otra aplicación en ejecución que utiliza el tiempo de ejecución de .NET. Sigo recibiendo OutOfMemoryExceptions. Sería bueno hacer que su aplicación se comporte para que otras aplicaciones no lancen excepciones cuando no pueden obtener suficientes recursos.