2012-02-14 7 views
5

Para un framework web probé métodos anónimos por primera vez y tuve un problema con la gestión de la memoria.Método anónimo en la memoria de filtraciones del proyecto

¿Cómo se puede reparar esta pérdida de memoria (Delphi 2009)?

El mensaje de fuga es:

13 - 20 bytes: Project27 $ ActRec x 1

program Project27; 

type 
    TTestProc = reference to procedure; 

    procedure CallMe(Proc: TTestProc); 
    begin 
    end; 

begin 
    CallMe(procedure begin end); 

    ReportMemoryLeaksOnShutdown := True; 
end. 

El mismo mensaje de fugas "Project27 $ ActRec x 1" no aparece ningún importa cuántos métodos anónimos están entre el comienzo y el final, supongo que la fuga es para el tipo de TTestProc, no los procedimientos anónimos individuales

program Project27; 

type 
    TTestProc = reference to procedure; 

    procedure CallMe(Proc: TTestProc); 
    begin 
    end; 

begin 

    ReportMemoryLeaksOnShutdown := True; 

    CallMe(procedure begin end); 

    CallMe(procedure var A: Integer; begin A := 42 ; end); 

end. 
+0

Esto se informó en 2009 como ['" Fugas de memoria QC78066 al utilizar métodos anónimos en el bloque de inicio ... de la unidad de programa "'] (http://qc.embarcadero.com/wc/qcmain .aspx? d = 78066). Aún no está arreglado. –

Respuesta

15

Cuando declara un método anónimo dentro de un procedimiento o función, se limpia cuando esa rutina se sale del alcance. (Esto es una simplificación excesiva, pero es lo suficientemente bueno para la discusión actual.) El problema es que la rutina principal del DPR no "está fuera del alcance". En cambio, el compilador Delphi inserta una llamada oculta al System.Halt al final de la misma, que nunca regresa.

Así que si lo escribe de esta manera, obtendrá la notificación de pérdida de memoria. Lo puede solucionar poniendo la creación método anónimo dentro de una rutina que sale normalmente, así:

program Project27; 

type 
    TTestProc = reference to procedure; 

    procedure CallMe(Proc: TTestProc); 
    begin 
    end; 

    procedure Test; 
    begin 
    CallMe(procedure begin end); 
    end; 

begin 
    Test; 
    ReportMemoryLeaksOnShutdown := True; 
end. 
+3

Hay más que eso de hecho. Si declara una variable de interfaz con alcance global en el archivo .dpr y la asigna, entonces se ordena antes de que se ejecute la comprobación de fugas. Los métodos de Anon son claramente especiales. –

+1

@David: Eso es extraño. Suena como un error, entonces. Alguien debería enviar un informe de control de calidad para ello. –

+0

Nadie debería hacer nada entre el principio y el final en .dpr que no sea invocar una función escrita en otra unidad. Incluso declarar el procedimiento directamente en .dpr es una práctica terrible, y es un mal estilo. –

10

supongo que esto se debe a que está utilizando el principal begin..end. bloque dentro del archivo .dpr. Las estructuras de memoria oculta creadas dentro del alcance begin..end. no se liberan cuando FastMM4 inspecciona la memoria, porque aún no está fuera del alcance.

No hay pérdida de memoria si coloca su método anónimo fuera de este bloque principal begin..end..

Mi consejo es evitar poner algún código dentro del archivo .dpr - en la mayoría de los casos falta. Y al IDE no le gusta eso. Use una unidad separada para su propio código y deje solo el contenido .dpr. :)

+0

Aunque estoy de acuerdo en que esa es la mejor opción para código no trivial, a menudo pongo todo en el dpr cuando pruebo algunos algoritmos en un programa de consola. Pero incluso entonces, mis anonmethos e interfaces, etc. son todos locales para las funciones (en el dpr), nunca en el bloque principal. –

Cuestiones relacionadas