Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Liberar forms (https://www.clubdelphi.com/foros/showthread.php?t=85500)

jlrbotella 26-03-2014 09:21:53

Liberar forms
 
Hola compañeros:

¿Sabéis como se puede liberar la memoria de un Form?. Actualmente realizo estos procedimientos, pero realmente no me libera la memoria:

Ejemplo 1

Código Delphi [-]
var
  fVentana : TForm2;
begin
  try
    fVentana := TForm2.Create(nil);
    fVentana.ShowModal;
  finally
    fVentana.free;
  end;

  ShowMessage(fVentana.variable); // Aquí debería fallar pero no lo hace
end;

Ejemplo 2

Código Delphi [-]
var
  fVentana : TForm2;
begin
  try
    fVentana := TForm2.Create(nil);
    fVentana.ShowModal;
  finally
    fVentana.free;
    fVentana := nil;
  end;

  ShowMessage(fVentana.variable); // Aquí falla
end;

olbeup 26-03-2014 09:28:34

Cita:

Empezado por jlrbotella (Mensaje 474335)
Hola compañeros:

¿Sabéis como se puede liberar la memoria de un Form?. Actualmente realizo estos procedimientos, pero realmente no me libera la memoria:

Ejemplo 1

Código Delphi [-]
var
  fVentana : TForm2;
begin
  try
    fVentana := TForm2.Create(nil);
    fVentana.ShowModal;
  finally
    fVentana.free;
  end;

  ShowMessage(fVentana.variable); // Aquí debería fallar pero no lo hace
end;

Ejemplo 2

Código Delphi [-]
var
  fVentana : TForm2;
begin
  try
    fVentana := TForm2.Create(nil);
    fVentana.ShowModal;
  finally
    fVentana.free;
    fVentana := nil;
  end;

  ShowMessage(fVentana.variable); // Aquí falla
end;

Hola jlrbotella,

El Ejemplo 2, es la mejor forma de hacerlo, también está el FreeAndNil(fVentana) que hace lo mismo pero en una sola línea.

Un saludo.

Neftali [Germán.Estévez] 26-03-2014 10:07:24

En realidad ambos son iguales en cuanto a la liberación de memoria, ya que la instrucción que realmente libera la memoria es el FREE. La asignación a nil, simplemente asigna ese valor a la variable que apunta al form, pero en ese momento la memoria ya se ha liberado(*).

(*)Recuerda, que el sistema no libera la memoria inmediatamente, así que si miras la memoria que consume tu programa, tal vez después de hacer el FREE, la cantidad de memoria libre siga siendo la misma que antes de hacerlo; Es normal, pues lo que hace el sistema es "marcar" determinada memoria, como que está "libre", pero no la libera en ese momento de forma explícita. Queda marcada y en el momento que el sistema la necesita "recopila" esas zonas "marcadas para liberar" y las "libera" todas al mismo tiempo.

Tal como comenta [olbeup], puedes usar un FreeAndNil, que lo que hace es hacer el FREE y la asignación en una misma instrucción(línea).

La asignación a NIL, aunque no es obligatoria, si es recomendable si posteriormente utilizas instrucciones como esta:

Código Delphi [-]
  if Assigned(miForm)...

radenf 26-03-2014 11:03:31

Estimado jrlbotella :

En este link se muestran otras alternativas.
Yo utilizo en mis programas el código que se muestra en el hilo #10, con exelentes resultados, que se pueden comprobar en el Administrador de tareas.

Saludos

Neftali [Germán.Estévez] 26-03-2014 12:50:20

El truco que comenta [radenf], tal y como explica Ian Martins aquí es "obligar" al sistema a liberar la memoria que tu programa tiene en ese estado "marcada para liberar" que he comentado antes.

El problema es que hay quien piensa que eso puede no ser todo lo beneficioso que a priori parece. Es decir, de alguna forma le estamos diciendo al sistema (obligándole) que queremos que liberar la memoria de nuestro proceso, cuando el sistema tiene su propio sistema de liberación. En cierta manera estamos interfiriendo en el correcto(normal) funcionamiento de este proceso.
¿Y si el sistema piensa que es mejor liberar la memoria de otro proceso, en lugar del nuestro?
¿Y si el sistema puede coger memoria de otro lugar sin necesidad de liberarla ahora (de nuestro proceso o de ningún otro)?
¿Y si el sistema piensa que ahora no es el momento de liberar?
¿...?

Lo que quiero decir es que no va a pasar nada por hacerlo, pero a lo mejor en algunos casos lanzar este proceso cada X tiempo, puede empeorar el rendimiento en lugar de mejorarlo (link -si buscas encontarás otros similares-).

Casimiro Notevi 26-03-2014 13:25:13

El "método Marteens" lo he usado desde siempre ¿1998? y con muy buenos resultados.

radenf 26-03-2014 19:07:50

Yo lo utilizo en mi programa para visualizar imágenes médicas en formato Dicom, que eleva el uso de la Ram en mas de 1Gb cada vez que cargo un nuevo examen (500-1500 Imágenes) y funciona a la perfección. Si no lo utilizo al cargar el segundo o tercer examen recibo el fatídico mensaje de que no dispongo de memoria suficiente.

Salu2

roman 26-03-2014 20:32:44

En mi opinión, los tres últimos mensajes (Neftalí, Casimiro y radenf) llevan razón.

El método de Marteens no tiene porqué fallar, como dice Casimiro, pero sí puede hacer la aplicación un poquillo menos eficiente (aunque en muchas ocasiones sea casi imperceptible) pues, como dice Neftalí, el sistema puede tener un mejor momento para hacer su trabajo (podemos pedirle al intendente que limpie nuestro lugar cada vez que derramamos un poco de café pero no es realmente necesario y el intendente hará mejor su trabajo si no lo interrumpimos a cada momento).

Pero habrá situaciones como las que describe radenf en que el uso de memoria es tan demandante que sea preferible limpiar cuanto antes (por ejemplo, si se nos cae toda la taza de café, seguramente convendrá llamar al intendente de inmediato).

// Saludos

Chris 27-03-2014 15:35:12

La mejor forma de liberar la memoria utilizada por un formulario es hacerlo en el evento OnClose. Asignas la acción de cerrar a caFree. De esta forma el formulario se liberará automáticamente y evitas estarlo liberando en cada código donde lo utilices. Por ejemplo:

Código Delphi [-]
procedure TForm2.OnClose(Sender: TObject, var Action: TCloseAction);
begin
    // liberar memoria actomáticamente
    action := caFree;
end;

Con lo anterior, tu código se simplicaría:
Código Delphi [-]
var
  fVentana : TForm2;
begin
  try
    fVentana := TForm2.Create(nil);
    fVentana.ShowModal();
  finally
    // do nothing
  end;
end;

Neftali [Germán.Estévez] 27-03-2014 15:52:55

Cita:

Empezado por Chris (Mensaje 474401)
La mejor forma de liberar la memoria utilizada por un formulario es hacerlo en el evento OnClose.

El problema es que a veces necesitas acceder al formulario (por ejemplo a una de sus propiedades) después de cerrarlo.
Para eso existen otras opciones como caHide.

En esos casos no puedes liberarlo de esa forma, así que yo no diría que es la "mejor". Simplemente es la adecuada para unas situaciones y no es adecuada para otras.

Al González 27-03-2014 17:09:49

Bueno, hablando de simplificaciones al usar formularios, yo prefiero escribir:
Código Delphi [-]
TForm1.Execute;  // Esto crea el formulario, llama a ShowModal y lo libera al cerrarse
El secreto es cambiar la declaración:
Código Delphi [-]
  TForm1 = class(TForm)
por:
Código Delphi [-]
  TForm1 = class(TghForm)

TghForm, que deriva de TForm, es una de las clases de GH Freebrary.

Un saludo. :)

Al González.

Casimiro Notevi 27-03-2014 18:05:50

Cita:

Empezado por Neftali (Mensaje 474403)
El problema es que a veces necesitas acceder al formulario (por ejemplo a una de sus propiedades) después de cerrarlo.
Para eso existen otras opciones como caHide.
En esos casos no puedes liberarlo de esa forma, así que yo no diría que es la "mejor". Simplemente es la adecuada para unas situaciones y no es adecuada para otras.

Ocurre muchas veces.


La franja horaria es GMT +2. Ahora son las 05:09:34.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi