[delphi] Na open dialog veel geheugengebruik

Pagina: 1
Acties:

  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
Als ik op een formpje een open dialog plaats, en daar een file in laat openen (ik hoef alleen de path naar de file te weten) en het dialog wordt dat weer gesloten, heeft mijn programma in een keer een verhoging van 2MB in gegeugen gebruik gekregen! Dit is natuurlijk niet erg fijn. Daarom is mijn vraag, hoe kan ik dat tegen gaan, of weer oplossen/geheugen cleanen.
N.B: Ik heb het zelfde resultaat met de PromptForFileName functie.

  • Postman
  • Registratie: Februari 2000
  • Laatst online: 15-08 20:11
Wordt het geheugen niet weer vrijgegeven nadat het dialog is gesloten?? Ik weet niet veel van memory allocation in Delphi, of Garbage collection.
Dat ie 2MB geheugen alloceert is op zich niet zo vreemd (is ook OS gerelateerd eigenlijk). Dat ie het niet meer vrijgeeft is wat vreemder :/

@ Lordlarry: ik mag idd hopen van niet. Externe programma's specifiek gemaakt voor geheugengebruik zijn wel een vereiste als je wilt controleren op geheugengebruik. Ik heb zelf wel eens een verschil van 50MB gezien met de Task Manager en een los programma (op een systeem van 256MB).

[ Voor 34% gewijzigd door Postman op 08-03-2003 23:10 ]


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Laat even wat code zien, mijn glazenbol is naar de garage...

/edit
Ow, en hoe ben je er zo zeker van dat je geheugen niet meer teruggegeven wordt? Waar controleer je het geheugen gebruik? Toch niet in de Task Manager bij Mem. Usage hoop ik. :)

[ Voor 61% gewijzigd door LordLarry op 08-03-2003 23:04 ]

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


  • Nibble
  • Registratie: Juli 2001
  • Laatst online: 16-08 02:25
Delphi heeft voor zover _ik_ weet geen autmatische garbage collector.
Alles wat je maakt met NEW moet je ook weer opruimen.
Aan de andere kant, als je een component erop sleurt, dan hoeft dat niet.
OpenFileDialog1.Execute etc... en ik neem aan dat dat het geval is.
Dan zou ik het eerder in een andere hoek zoeken, of echt eens door je code heen gaan tracen waar het precies zit. (CPU window kun je ook gebruiken!)

T is for TANK, and T is for TERROR ... and K is the K for KILLING in error.


  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
LordLarry schreef op 08 March 2003 @ 23:01:Ow, en hoe ben je er zo zeker van dat je geheugen niet meer teruggegeven wordt? Waar controleer je het geheugen gebruik? Toch niet in de Task Manager bij Mem. Usage hoop ik. :)
Euh, gewoon in de Task Manager dus... Wat is daar dan mis mee? En hoe zou ik het dan anders moeten zien?
Delphi:
1
2
3
4
if Opendialog.Execute then
begin
  VariableVoorFilename := Opendialog.FileName;
end;

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

oikoyama schreef op 08 maart 2003 @ 23:20:
[...]

Euh, gewoon in de Task Manager dus... Wat is daar dan mis mee? En hoe zou ik het dan anders moeten zien?
Minimize je applicatie eens, ben je dan opeens een boel MB's aan geheugen kwijt? Niet te verklaren he? Dat komt omdat dat geheugen gebruik anders wordt geteld. Kijk eens bij de kolom VM. Size voor een reeeler beeld, maar gebruik liever een programma als (de gratis) MemProof (http://www.automatedqa.com/products/memproof.asp).

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


Verwijderd

Geen idee of het werkt ;)
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
var cdgOpen: TOpenDialog;
begin
  cdgOpen := TOpenDialog.Create(**);
  try
      if cdgOpen.Execute then 
      begin
          sFileName := cdgOpen.FileName;
      end;
  finally
    cdgOpen.Free;
    cdgOpen := nil;
  end;
end;


Waarom ondersteunt [code] pascal niej :P

[ Voor 10% gewijzigd door Verwijderd op 09-03-2003 00:42 ]


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 22:26

Tomatoman

Fulltime prutser

Het zou best weleens zo kunnen zijn dat er pas wat libraries worden geladen op het moment dat de TOpenDialog verschijnt en dat die pas weer worden vrijgegeven als je programma afsluit. Daar is niets vreemds aan. Op die manier worden niet onnodig allerlei libraries geladen, maar wordt voorkomen dat je applicatie voortdurend libraries laadt en weer vrijgeeft telkens als je een dialogvenster laat zien.

Ik weet niet zeker of dat dat is wat er bij jou gebeurt, maar het is wel een aannemelijk scenario. Eenmalig twee megabyte extra geheugengebruik is wat dat betreft niet vreemd.

Een goede grap mag vrienden kosten.


Verwijderd

Er wordt iig cmndlg32.dlg geladen :)
naja. zoiets dan ;)

[ Voor 23% gewijzigd door Verwijderd op 09-03-2003 04:27 ]


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 22:26

Tomatoman

Fulltime prutser

Hé reyer, ga naar die Formule 1 race kijken of ga naar bed! Dit is geen tijd om nog aan het proggen te zijn :)

Een goede grap mag vrienden kosten.


Verwijderd

Ik was Formule 1 kijken ;)

Verwijderd

Ik weet niet of dit is wat jullie bedoelen:

code:
1
2
opendialog1.Free;
opendialog1 := Topendialog.Create(nil);


Dit werkt bij mij goed. Al heb ik nooit naar het eventuele geheugengebruik gekeken.

  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
Ik heb dat MemProof maar eens geprobeerd (2e keer, want ik snap er de balle van) en als ik dan een beetje heb zitten te knommelen, en het programma weer sluit, krijg ik de leuke mededeling dat ik 1847× (!) een resource niet heb gefreed (wat een woord).
Nu ben ik niet zo lang bezig met delphi, en heb dus geen idee waar ik moet zoeken, en waar dus die lekjes zitten.
Deze komt heel vaak voor:
API Name: GetMem, Module: RTL.
GetMem allocates memory from the RTL memory manager and returns a pointer. The returned pointer must be freed with FreeMem.
Ze hebben maar een kleine size: ~50, maar het zijn er wel héél erg veel.

  • Weng
  • Registratie: Juni 2001
  • Laatst online: 11-05-2024

Weng

Are y'all ready kids

Verwijderd schreef op 09 March 2003 @ 13:12:
Ik weet niet of dit is wat jullie bedoelen:

code:
1
2
opendialog1.Free;
opendialog1 := Topendialog.Create(nil);


Dit werkt bij mij goed. Al heb ik nooit naar het eventuele geheugengebruik gekeken.
Wat je hier doet is dat je het geheugen van opendialog vrijgeeft en daarna weer inneemt. Waarom geef je em dan vrij?

Ik ben het eens met wat Reyer schreef.
Je zou ook FreeAndNil( cdgOpen ) kunnen gebruiken.

Aye aye captain


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

oikoyama schreef op 09 March 2003 @ 17:02:
Ik heb dat MemProof maar eens geprobeerd (2e keer, want ik snap er de balle van) en als ik dan een beetje heb zitten te knommelen, en het programma weer sluit, krijg ik de leuke mededeling dat ik 1847× (!) een resource niet heb gefreed (wat een woord).
Nu ben ik niet zo lang bezig met delphi, en heb dus geen idee waar ik moet zoeken, en waar dus die lekjes zitten.
Deze komt heel vaak voor:

[...]
Ze hebben maar een kleine size: ~50, maar het zijn er wel héél erg veel.
Als het goed is wordt ook verteld op welke regel en unit dit gebeurd. Memproof is een gratis programma en helaas wat verouderd. Het is bijvoorbeeld nog niet geschikt voor Delphi 7. Ook bevat het niet een up-to-date lijst van leaks die standaard in windows en/of Delphi zitten. Het kan dus zo zijn dat de leak die jij gevonden hebt helemaal niet jouw schuld is.

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


  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
LordLarry schreef op 09 March 2003 @ 17:48:
Het is bijvoorbeeld nog niet geschikt voor Delphi 7.
Aaaah... Ik d8 al, ik kan niets van die beloofde features vinden :) Ik gebruik dus D7. Jammer voor mij dus :( In Delphi 6 openen is een beetje hobby, omdat ik dan alle gebruikte componentjes moet gaan installeren... En dan is het weer dag met de XP style support...

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 22-06 10:32

_Thanatos_

Ja, en kaal

ff offtopic, maar het moet gemeld worden...
En dan is het weer dag met de XP style support...
Newbie ;)
Nooit van ThemeManager gehoord zeker.

日本!🎌


  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
Ok, ik ben een newbie, maar ik weet dan nog wel dat D6 geen native XP style support heeft. Plaats maar eens een PageControl op je D6 form, met een XPManifest. Zie je dan dat er een mooi egaal vlak komt? Zie het verschil in D7. Ik bedoel maar. Trwns, D7 loopt hier veel beter... :)

Maar als ik het dus goed begrijp is het bijna niet te tracken of te fixen waar die memory leak nu ligt. Athans, op dit moment dan. Als D7 support in dat proggie zit, dan nat. wel.

  • Paul
  • Registratie: September 2000
  • Laatst online: 19-08 15:39
Verwijderd schreef op 09 March 2003 @ 13:12:
Ik weet niet of dit is wat jullie bedoelen:

code:
1
2
opendialog1.Free;
opendialog1 := Topendialog.Create(nil);


Dit werkt bij mij goed. Al heb ik nooit naar het eventuele geheugengebruik gekeken.
Als je een component op je form hebt gepleurt en dan dit aanroept bem je dus al je instellingen kwijt (je filter, je flags (FileMustExist etc))...
Heb je geen component maar staat daar ergens boven "var opendialog1: TOpenDialog;" dan klapt hij eruit met een NullPointerException oid. Je hebt dan wel openDialog1 gedeclareerd, maar niet geinitialiseerd, en die is dus nog NULL. Roep je hem dan aan dan zegt hij "Ja doei, wat moet ik hier mee? Dit ken ik niet..." :)

Wat je kunt proberen als er dus daadwerkelijk een geheugenlek en TOpenDialog zit, is zelf API-calls maken. Staan allemaal in de Win32 Programmers Reference in een subdir van je Delphi Startmenu.

[Edit] Voor het opsporen van geheugenlekken (vaak met regelnummer erbij :) ) onder Delphi gebruik ik MemCheck.pas. Geen idee waar ik die weg heb gehaald, ik zal ff zoeken... Heeft nl wel een gebruiksaanwijzing (wat compiler en linker instellingen en zo).

Edit2: Gevonden: http://v.mahon.free.fr/pro/freeware/memcheck/

[ Voor 17% gewijzigd door Paul op 11-03-2003 00:31 ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
Paul Nieuwkamp schreef op 11 March 2003 @ 00:24:
Wat je kunt proberen als er dus daadwerkelijk een geheugenlek en TOpenDialog zit, is zelf API-calls maken. Staan allemaal in de Win32 Programmers Reference in een subdir van je Delphi Startmenu.
Ik heb daar ook al zitten te zoeken, omdat die window nogal Win achtig is, dus ik d8 daar zal wel een simpele API call voor zijn, maar heb helaas niets kunnen vinden. Weet toevallig iemand die wel?

  • Paul
  • Registratie: September 2000
  • Laatst online: 19-08 15:39
oikoyama schreef op 11 March 2003 @ 00:31:
[...]

Ik heb daar ook al zitten te zoeken, omdat die window nogal Win achtig is, dus ik d8 daar zal wel een simpele API call voor zijn, maar heb helaas niets kunnen vinden. Weet toevallig iemand die wel?
API calls zijn een hoop dingen, maar bijna nooit simpel :+ Nah, ik klets natuurlijk, maar je moet het even doorhebben.

Meestal is het enige resultaat van een functie een indicatie of hij gelukt is, de rest van de info (als je iets opvraagt) staat in de parameters van je functieaanroep. Er zijn genoeg voorbeeldjes te vinden, dus die behandel ik maar even niet (buiten het feit dat ik ze zelf nog nodig heb :P ), maar ik heb vaak TOpenDialog gebruikt, en MemCheck heeft nog nooit lekken gevonden. Ik denk dat het gewoon de taskmanager is die je beeld verkloot.

Ik heb nooit naar de code achter het OpenDialog-component gekeken, maar ik gok dat je niet zo gek veel meer dan wat API-calls tegenkomt.
Waar API-Calls dan goed voor zijn als er toch een Delphi-tegenhanger / implementatie is?

Als je bijvoorbeeld iets kleins wilt schrijven maar wel een MessageDlg wilt gebruiken. Je kunt dan kiezen voor het Usen van Dialogs (GROOT) of het rechtstreeks aanroepen van de API-call.
Ook kan het sneller zijn, zeker als je alles weglaat wat je toch niet gebruikt.
Waar je bij het zelf aanroepen van API-calls WEL goed op moet letten is het goed vrijgeven van alles. API-calls hangen van de pointers, buffers en char-arrays aan elkaar, en de meeste daarvan moeten geFREEd worden.

[ Voor 30% gewijzigd door Paul op 11-03-2003 00:38 ]

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • Just_a_Gamer
  • Registratie: November 2001
  • Laatst online: 00:00
_Thanatos_ schreef op 10 March 2003 @ 01:35:
ff offtopic, maar het moet gemeld worden...

[...]
Newbie ;)
Nooit van ThemeManager gehoord zeker.
count me in als een newbie :P Ook nooit van gehoord :+ Btw thank u voor de link.

[ Voor 5% gewijzigd door Just_a_Gamer op 11-03-2003 00:53 ]


  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
Paul Nieuwkamp schreef op 11 maart 2003 @ 00:34:Waar je bij het zelf aanroepen van API-calls WEL goed op moet letten is het goed vrijgeven van alles. API-calls hangen van de pointers, buffers en char-arrays aan elkaar, en de meeste daarvan moeten geFREEd worden.
Ik gebruik dan bijv. de api call MessageBox in de Windows unit, moet ik die dus daarna freed worden? (hoe doe ik dat dan?)

  • Paul
  • Registratie: September 2000
  • Laatst online: 19-08 15:39
oikoyama schreef op 11 March 2003 @ 01:01:
[...]
Ik gebruik dan bijv. de api call MessageBox in de Windows unit, moet ik die dus daarna freed worden? (hoe doe ik dat dan?)
De call zelf kun je niet free-en :) En als je gewoon (fictief voorbeeld, heb geen Delphi of helpfiles in de buurt, dus uit het hoofd, parameters zullen niet kloppen)
code:
1
2
3
MessageBox(PChar('nep-BSOD'),
           PChar('Er is een fout opgetreden in de module FOO.EXE'), 
           SW_een_leuke_switch)

gebruikt hoef je niets te free-en, maar zodra je een buffer aanmaakt omdat je een resultaat terug krijgt etc, dus bij de wat uitgebreider / lastiger API-calls zul je die buffers weer vrij moeten geven. (of ben ik nu zo brak dat ik deze verwar met de C(++) tegenhangers? Vlg mij moet ik gaan slapen :P Bikkelen is niets voor mij)

Je hoeft iig niets vrij te geven wat je niet zelf gedeclareerd hebt in een var-blok, en daarvan niet eens alles. Simpele types zoals integer, float en string hoeven niet. Al je klasse-instanties wel.

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • bgever
  • Registratie: April 2002
  • Laatst online: 28-05-2021
Paul Nieuwkamp schreef op 11 March 2003 @ 01:27:De call zelf kun je niet free-en :) En als je gewoon (fictief voorbeeld, heb geen Delphi of helpfiles in de buurt, dus uit het hoofd, parameters zullen niet kloppen)
Ah, je komt redelijk in de buurt, je bent de 1e vergeten: window handle. ;) Nee, maar dan weet ik dus genoeg:
Ik kan dus ook een open dialog krijgen door een api call uit te voeren (meen dat de functie die ik in het begin (firstpost) genoemd heb een api call daarvoor is), en daarna de var (die je moet opgeven, waar de filenaam in bewaard wodt) nog laterna moet freëen (heerlijk EN-NL). Maar hoe free ik dan die var?

  • matthijsln
  • Registratie: Augustus 2002
  • Laatst online: 30-07 16:33
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function GetOpenDialogFilename(wnd: HWND; Mask: string): string;
const
  BUF_SIZE = 1000;
var
  o: OPENFILENAME;
  filename: array[0..BUF_SIZE] of char;
begin
  filename[0] := #0;
  FillChar(o, SizeOf(o), 0);
  o.lStructSize := SizeOf(o);
  o.hwndOwner := wnd;
  o.lpstrFilter := @Mask[1];
  o.lpstrFile := @filename[0];
  o.nMaxFile := BUF_SIZE;
  o.Flags := OFN_FILEMUSTEXIST or OFN_HIDEREADONLY;
{$IFDEF FPC}
  if GetOpenFileName(@o) then
{$ELSE}
  if GetOpenFileName(o) then
{$ENDIF}
    result := string(PChar(@filename[0]))
  else
    result := '';
end;


BTW, het is normaal dat ook als je deze functie gebruikt je memusage enorm omhoog gaat. Dat komt gewoon door de common controls libary van Windows. Je krijgt er ook gelijk een paar threads bij die nog blijven leven na de API call...
Pagina: 1