Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 14-07-2003
susje susje is offline
Miembro
 
Registrado: jul 2003
Posts: 11
Poder: 0
susje Va por buen camino
Memoria

Buenas a todos:

¿Alguien me puede explicar como puedo hacer que una aplicacion en delphi no aumente de memoria tanto?
Creo que estoy cerrando todos los objetos, pero la aplicacion sigue subiendo de memoria hasta el limite que da el error de "out of memory".


Saludos.
Responder Con Cita
  #2  
Antiguo 14-07-2003
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
No explicas mucho que es lo que haces y no es normal que te ocurra lo que nos cuentas.

Para empezar, mira a ver cuantas Formularios tienes en AutoCreate, no debieran pasar de 2 ó 3, el resto tendrías que pasarlos a disponibles "Available", y solamente crearlos cuando vayan a utilizarse.

.......

Un Saludo.
Responder Con Cita
  #3  
Antiguo 14-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
No es la solución, pero te recomiendo leer este hilo http://www.clubdelphi.com/foros/show...=&threadid=253

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #4  
Antiguo 14-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

Tal vez tengas una fuga de memória. Los componentes visuales, tienen una propiedad parent que indica quien es el responsable de liberarlo. De forma que al eliminar un formulario, se libera la memória de todos los componentes que lo tengan como parent.

Aunque a veces se crean objetos por código, los cuales se tienen que liberar también por código mediante el método Free, puesto que al liberar el formulario donde se crearon, no implica que se libere su memória asignada. Esto puede provocar que cada vez que cargas el formulario, se creen objetos nuevos por código, los cuales al no liberarse nunca, van incrementado gradualmente la memória consumida.

Ejemplo :

Código:
procedure TfrmAnomalia.CargarImagen;
var Jpeg:TJpegImage;
    Corriente:TMemoryStream;
begin
  imgFoto.Picture := nil;
  if cdsDatosIMAGEN.BlobSize > 0  then begin
    Jpeg:=TJpegImage.create;
    Corriente:=TMemoryStream.create;
    try
      cdsDatosIMAGEN.SaveToStream(Corriente);
      Corriente.Seek(0,soFromBeginning);
      Jpeg.LoadFromStream(Corriente);
      imgFoto.Picture.Assign(Jpeg);
    finally
      Jpeg.Free;                   (*)
      Corriente.Free;             (*)
    end;
  end;
end;
Estas líneas, cargan en un TImage, una imagen en formato Jpeg guardada en un campo Blob. En los (*) se muestra como libero unos objetos creados por código. Si no lo hiciese, cada vez que cargase el formulario, tendría una perdida de memória, con el contenido de la imagen.

No estaría de más que revisases tu código buscando objetos sin liberar.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #5  
Antiguo 14-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Cita:
Posteado originalmente por guillotmarc
Los componentes visuales, tienen una propiedad parent que indica quien es el responsable de liberarlo.
Pero cuando tienes un TControl que no tiene Parent, o cualquier objeto heredado de TComponent, el que se encarga de eliminarlo es el Owner.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #6  
Antiguo 14-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

El problema normalmente aparece con los objetos que no heredan de TControl o TComponent (o sea los no visuales), o los componentes visuales que se hayan creado por código (y por lo que no se asigna esa propiedad a menos que se indique especificamente).

NOTA : Seguramente habré confundido la propiedad Parent por la Owner, y ser este ultimo, como comentas, el responsable de la liberación del objeto.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 14-07-2003 a las 18:49:02.
Responder Con Cita
  #7  
Antiguo 14-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Entiendo a lo que apuntas, como suena medio raro tu aclaración, te comento que yo entiendo por "componentes visuales", aquellos heredados de TControl, ya sea TGraphicControl o TWinControl, en estos podemos utilizar Parent para la "auto-eliminación", y más arriba en la jerarquía, con los TComponents podemos utilizar Owner. En los TControls la propiedad Parent asume la funcionalidad de Owner al liberar todos su "hijos"... De todos modos me parece mas prolijo encargarse explícitamente de liberar los objetos no utilizados.


Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #8  
Antiguo 14-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Ahhh... me has cambiado el texto!!!... Ahora es en vano la aclaración que he hecho....


Saludos!

PD: Aún conservo una copia de tu texto anterior
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #9  
Antiguo 14-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Jejeje.

Lo siento, suelo releer los mensajes que envío, y muchas veces modifico lo que no me acaba de gustar.

Un saludo.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #10  
Antiguo 17-07-2003
Eduardo Eduardo is offline
Miembro
 
Registrado: jul 2003
Posts: 16
Poder: 0
Eduardo Va por buen camino
Hola, acabo de unirme a este foro. Antes de nada presentarme, hace años si usaba clubdelphi de forma habitual pero un cambio de trabajo y de vida hicieron que lo dejara. Ahora vuelvo y espero poder ayudar y recibir ayuda en delphi.
He leido los problemas de memoria de los que hablais. A mi me pasa lo mismo, trabajo con formularios que crean frames que crean controles en tiempo de ejecucion y cuando abro el formulario unas 10 veces a la onceaba dice que le falta memoria. Llevo bastante intentando buscar la solucion. En el frame he probado a poner
private
{ Private declarations }
Destructor Destroy; override;
Destructor tfr_camposb.Destroy;
begin
while controlcount <>0 do controls[0].free;
while componentcount <>0 do components[0].free;
inherited Destroy;
end;
y en el formulario lo mismo pero sigo con los mismos problemas. La cosa esta en que no se el nombre de los controles porque se crean a partir de los campos de la base de datos y en funcion de otras condiciones algo mas complicadas.
Tampoco tengo la certeza de cual no se esta destruyendo y donde se come la memoria. Si le hago una traza, pasa por los free y los ejecuta. He probado con el winsight para ver si me dice algo y nada. ¿como puedo saber que se ha quedado sin destruir? ¿teneis algun truco para saberlo?

Estaba trabajando con delphi 5 y ahora lo he compilado con delphi 7 y sigue con los mismos problemas.

Gracias por cualquier sugerencia.
__________________
Eduardo
Responder Con Cita
  #11  
Antiguo 17-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

La sobreescritura que haces del método Destroy no es necesaria. Puesto que solo liberas los componentes que ya tienen asignado Parent o Owner, dado que són los unicos que te saldrán en la colección Controls y Components respectivamente. Y estos controles y componentes ya són liberados automaticamente al liberar el formulario.

Lo que tendrías que buscar són controles y componentes que hayas creado, y a los que no asignas correctamente su padre (en Parent o Owner). Puesto que estos son los que al liberarse el padre, no serán liberados automaticamente. También puedes tener objetos (no controles o componentes) creados en el código, los cuales se tienen que liberar una vez usados, como en el ejemplo que puse con objetos de la clase TJpegImage y TMemoryStream.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #12  
Antiguo 17-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Insisto con esto http://www.marteens.com/trick42.htm
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #13  
Antiguo 17-07-2003
Eduardo Eduardo is offline
Miembro
 
Registrado: jul 2003
Posts: 16
Poder: 0
Eduardo Va por buen camino
Hola
No es por no ir, como dirian unos humoristas españoles, pero ir por ir ....

No es este el caso, el caso es que llevo 2 años desarrollando sobre la misma aplicacion, es practicamente una herramienta para hacer aplicaciones de gestion. Crea automaticamente los formularios, relaciones, integridades referenciales, etc. Imaginate la cantidad de codigo. Por eso me gustaria saber si existe algun truco, alguna manera de listar los controles y/o los componentes sin 'padre'. De esta forma veria rapidamente donde puede estar el problema y al mismo tiempo nos serviria para futuros desarrollos. Se pondria como una especie de control antes de la salida de la aplicacioin que avise al programador de que lo que ha echo no esta bien. Hombre! si delphi o alguna utilidad tuviera esa prestacion, yo la he buscado en el winsight y no lo he localizado, no haria falta ese lio.

Gracias por cualquier comentario
__________________
Eduardo
Responder Con Cita
  #14  
Antiguo 17-07-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 23
guillotmarc Va por buen camino
Hola.

Hay algunos programas para detectar estas fugas de memória. Por ejemplo el MemProof de Atanas Stoyanov.

http://www.automatedqa.com/

En la web hay su catálogo de programas comerciales de testeo de aplicación, pero en Downloads puedes descargar gratuitamente el MemProof.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #15  
Antiguo 17-07-2003
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
De cualquier forma no vas a poder detectar automáticamente los controles sin parent o los componentes sin owner.

Lo que podes hacer es ubicar, con grep o con una busqueda es ubicar todas las llamadas a Create, y aunque te lleve un buen tiempo, revisar que siempre se asigne el parent y el owner.

De hecho, con los componentes, el owner regularmente se asigna en la llamada al constructor, digamos una llamada de la forma

Código:
Procedure TForm1.CrearObjetos;

Var
  ComponenteX : TMiComponente;

Begin
  ComponenteX := TMiComponente.Create(Self);
end;
Asigna la instancia de Form1 como owner de ComponenteX;

Será tedioso, pero es necesario.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #16  
Antiguo 18-07-2003
Eduardo Eduardo is offline
Miembro
 
Registrado: jul 2003
Posts: 16
Poder: 0
Eduardo Va por buen camino
Ante todo, gracias a todos los que me habeis ayudado.

Por fin he dado con el problema

Como decia al principio, mi aplicacion se basa en formularios que se crean en tiempo de ejecucion.

Las tablas las tengo puestas en frames, de forma que por ejemplo, la tabla de facturas esta en un frame que tiene la misma tabla, el datasource y las tablas que tienen relacion, en este caso, la de clientes, forma de pago, etc.

Si este frame contenedor de tabla tiene alguna relacion algo mas fuerte con otro frame, por ejemplo, el de facturas con las lineas de facturas, lo que hago es colocar dentro del frame de facturas el frame de lineas de facturas, y dentro de este ultimo el de movimientos de almacen, con lo cual me llevo todas las posibles relaciones ya creadas. Esta filosofia, que a simple vista puede resultar complicada, luego es muy efectiva. Yo he trabajado con datamodules durante varios años y los problemas eran horrorosos. Con frames todo funciona como la seda. Si en un caso especial quiero acudir a la tabla solo sin sus relaciones esenciales, pues la pongo y punto, este es el caso de que quiera consultar unos totales de factura pero en ese caso no me interesen los datos de clientes o forma de pago. De la misma forma, si quiero usar la tabla con todas sus relaciones, pongo el frame en lugar de la tabla y heredo todo.

Los formularios lo que hacen es leerse los frames con las tablas, los campos y las relaciones y crean mantenimientos.

Yo pensaba que se me habia ido destructores en estos formularios, es decir, que creaba los controles y luego no los destruia. Y me he vuelto loco buscandolos.

El problema era mas sencillo de lo que parecia. He cojido el memprof que me habeis aconsejado y lo he ejecutado contra mi aplicacion. Es impresionante, y para mi al mismo tiempo era desconsolador, unos formularios perdian memoria y otros no sin razon aparente. Al final vi una opcion en el memprof que me permitia ver las tablas abiertas, y descubro que si un formulario abre por ejemplo 30 tablas, al cerrarlo solo me cierra 23, cuando otro si lo hace bien. Yendo por este camino descubri que unos de mis frames preferidos le creaba un frame dentro de este en tiempo de ejecucion y con un create(nil) ¡toma ya!. He reconstruido el codigo para que lo creara correctamente y ya funciona todo de maravillas.

Guardare el memprof a buen recaudo. Es una herramienta imprescindible. Por cierto, que ese programa que tanto publican en esta misma web de testeo pero que tiene coste. Esta en ingles y mi ingles es bastante pobre. Alguien me puede orientar o darme alguna direccion web en español donde pueda aprender.

Gracias de nuevo
__________________
Eduardo
Responder Con Cita
  #17  
Antiguo 18-07-2003
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Aha!!... esos es una demostración de que no hay que echarle la culpa al lenguaje hasta no estar seguros de quien es el culpable!!

Te agrego que cuando jachguate escribió su mensaje, yo estaba por "refutarlo" (porque lo había malentendido) diciendo que si un componente pertenece a un form o cualquier otro componente, estamos "obligados" a asignarle el owner, si es que queremos ser prolijos.
Agrego otro tema que me parece muy importante, y he visto muchos programadores experimentados que lo pasan por alto:

Cuando creamos una instancia de un objeto que vamos a eliminar en el mismo procedimiento, es MUY IMPORTANTE que escribamos un try...finally para siempre liberarlo.

Código:
var
  MiObj: TObject;
begin
  MiObj := TObject.Create;
  Try
     ...
  finally
    MiObj.Free;
  end;
Saludos!!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #18  
Antiguo 18-07-2003
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Cita:
Posteado originalmente por delphi.com.ar

Te agrego que cuando jachguate escribió su mensaje, yo estaba por "refutarlo"
Por re--- queeeee?????

recorcholis...



Hasta luego.

pd. Crei que me estabas maltratando... porque te habia malentendido... jejejeje


__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #19  
Antiguo 23-07-2003
susje susje is offline
Miembro
 
Registrado: jul 2003
Posts: 11
Poder: 0
susje Va por buen camino
Hola a todos,
Acabo de ver los mensajes y me he decido a descargar el programa MemProf pero creo que no lo se utilizar del todo bien
¿Alguien me puede explicar cual es su funcionamiento?¿Como puedo ver los objetos que no liberan memoria?.

Saludos.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 10:41:57.


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
Copyright 1996-2007 Club Delphi