[Delphi] Dynamisch frames inladen

Pagina: 1
Acties:

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Topicstarter
Waarom dit topic...
Ook vanwege de oproep van tomatoman om meer Delphi topics, open ik nu dit topic ;). Maar vooral om even iets te controleren...
Aangezien ik deze werkwijze zelf heb bedacht (wat natuurlijk niet wil zeggen dat ik de enige ben die dit zo doet... :+) heb ik gezocht, maar niet heel veel gevonden.

Situatie
Om een applicatie te maken welke veel verschillende schermen gebruikt, heb ik alle benodigde schermen als frame gemaakt. Zodra een van deze frames getoond moet worden wordt het dynamisch geladen en krijgt 't als parent het mainform. Hierdoor is de inhoud van het frame zichtbaar op het mainform. Afhankelijk van de opbouw is dan zelfs niet zichtbaar dat het een ander scherm betreft.

Question?
Het hoofdscherm heeft een variabele tlf (een TFrame) waarin het op dat moment benodigde frame geladen wordt, door de volgende regel:
Delphi:
1
  tlf := TBenodigdFrame.Create(nil);
Vervolgens wordt de parent-property van tlf op het hoofdcherm gezet. Na alle bewerkingen en acties die op het frame uitgevoerd zijn, wordt het frame vrijgegeven door de volgende regels
Delphi:
1
2
  tlf.Free;
  tlf := nil;
In principe zou ik denken dat dit goed gaat. Na de .free van de tlf bevat deze echter nog wel 'iets' volgens de watch die ik eraan gehangen heb. Als ik vervolgens verschillende keren tussen twee van deze frames wissel, loopt het geheugengebruik van de betreffende applicatie redelijk stevig omhoog. En dat wil volgens mij zeggen dat niet alles netjes wordt vrijgegeven :?. Heeft iemand een idee waarom Delphi het geheugen van het frame niet netjes vrijgeeft, ondanks dat ik de .Free aanroep?

Edit:
Zit net te denken.... Is het nodig dat ik tlf eerst cast naar het huidige, geladen frame, of zou het free-en van tlf zelf voldoende moeten zijn?

[ Voor 7% gewijzigd door OZ-Gump op 23-01-2004 10:11 ]

My personal website


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Nee, Free zou al voldoende moeten zijn. Tenzij je nog dingen doet die wij niet kunnen zien :) Als je geen := nil doet blijft tlf nog wel ergens naar verwijzen en daar kan zelfs lange tijd nog dezelfde gegevens in blijven staan als voor de Free. Toch is dit stuk geheugen aangemeld als vrijgegeven en kan het elk moment gerecycled worden en overschreven worden.

Maar hoe trek je de conclusie dat het geheugengebruikt blijft oplopen? Mem Usage van de Task Manager geeft een heel ander beeldt dan de meeste mensen verwachten. Minimize en restore je applicatie maar. Plotseling gebruikt je applicatie veel minder als daarvoor?! Voor een relaistischer kijk zou je moeten kijken naar de VM Size moeten kijken. Toch blijft die ook meestal omhoog lopen bij een Delphi applicatie. Dat komt omdat Delphi zijn eigen memory manager heeft en die recycled de boel intern en geeft niet alles meteen terug aan windows.

We adore chaos because we like to restore order - M.C. Escher


  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Topicstarter
@LordLarry: inderdaad, ik ben misschien iets te blind gevaren op de task manager ;). Ik had natuurlijk eigenlijk moeten weten dat ik het gewoon goed gemaakt had :Y).

Dat met dat minimaliseren is natuurlijk geniaal...! Ik zou echter wel graag iets duidelijker willen weten hoe mijn applicatie nou met zijn geheugen omgaat, en met eventuele andere resources. Ik meen me te herinneren dat ik ooit ergens een keer een applicatie voorbij heb zien komen waarmee memory management van een applicatie redelijk goed te testen was. Maar denk je dat ik die nu nog kan vinden.... :? In ieder geval wel tof dat ik nu iets zekerder weet dat het stiekem wel goed is.

Ik kwam overigens ook op die gedachte omdat een collega van me een vergelijkbare methode had gebruikt (lees: gejat ;)) en zijn 'oude' frame bleef zichtbaar na een free. Dit had echter te maken met het feit dat hij direct weer een ander frame in de variabele laadde. Een repaint tussen de
Delphi:
1
2
  tlf.free;
  tlf := nil
en de
Delphi:
1
  tlf := TAnderFrame.Create(nil);
was genoeg...

My personal website


Verwijderd

Maar als de oude frame nog zichtbaar is, en nog opnieuw getekend kan worden, na de tlf:=nil bestaat het component ook nog in het geheugen, wat dan dus niet vrijgegeven wordt.
Als zou ik zeggen dat de free en :=nil genoeg moeten zijn om het te verwijderen.

  • OZ-Gump
  • Registratie: November 2002
  • Laatst online: 14-05-2024

OZ-Gump

terug van weggeweest

Topicstarter
De repaint waar ik het over heb is er een op het hoofdscherm, niet het frame ;).

Door deze repaint is juist duidelijk geworden dat het frame vrijgegeven is, omdat de variabele tlf het mainform als parent heeft. Was tlf nog geassigned geweest, dan was deze ook gerepaint. Dus is tlf free.....

Wazig zin, maar volgens mij klopt het wel ;)

My personal website


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Je kan met AQTime goed bekijken wat je geheugen gebruik is binnen je Delphi applicatie en meer. Als je het in je eigen applicatie in de gaten wil houden kan je kijken naar de GetHeapStatus functie.

We adore chaos because we like to restore order - M.C. Escher


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 06-03 20:19

_Thanatos_

Ja, en kaal

Of met MemProof, die is gratis, maar heeft wel een aantal vervelende glitches (hij kijkt soms naar de verkeerde source, of de stack trace traceert niet naar de methode waar het eigenlijk om gaat)

Maar het is wel gratis :Y)

日本!🎌


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 06-05 18:51

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 23 januari 2004 @ 11:49:
Maar als de oude frame nog zichtbaar is, en nog opnieuw getekend kan worden, na de tlf:=nil bestaat het component ook nog in het geheugen, wat dan dus niet vrijgegeven wordt.
Als zou ik zeggen dat de free en :=nil genoeg moeten zijn om het te verwijderen.
Nope. Bij een free is dat ding echt weg uit het geheugen. NIL toekennen aan de variabele geeft alleen aan dat die var nergens meer naar wijst.

Dit allemaal zegt helemaal niks over wat er op het scherm staat. Als je eenmaal iets op het scherm tekent, dan blijft dat daar lekker staat totdat er weer overheen getekend wordt. Als je dus een Frame op een form streamt en dat eerste frame tekent en het form daarna niet meer ververst, dan kan je daarna rustig dat frame free'en terwijl het wel zichtbaar blijft op het form. Totdat je er dus wat overheen tekent.

Voor het free'en van tlf hoef je dat ding niet te casten naar het juiste type. Je kan rustig tlf zelf ene free geven en Delphi zoekt zelf wel uit wat voor type het nu echt was.

[ Voor 12% gewijzigd door Creepy op 23-01-2004 13:30 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 19:24

alienfruit

the alien you never expected

Je kunt toch ook FreeAndNil() gebruiken (SysUtils.pas)
Pagina: 1