Avatar billede coladrenge Nybegynder
20. januar 2007 - 10:06 Der er 9 kommentarer og
2 løsninger

Frigivelse af hukommelse efter brug af AdoTable

Hej

Jeg har skrevet en stor applikation som gør brug af adotabels - hvis jeg havde tiden ville jeg gerne bruge query istedet, men der er tale om en kæmpe application aom det har taget 3 - 4 år at lave. Der er cirka 170 skærmbilleder og små 100 dataklasser.

Problemet er at når en table bruges bruger systemet rigtigt meget hukommelse og den hukommelse frigives ikke igen. Eksempelvis er det ikke usædvanligt at en pc'er efterhånden som dagen går bruger 500 mb. hukommelse selv om appliacationen ikke bruger den til noget. Kører man så et program som Ram Booster export så bruger programmet 20 - 30 mb. hukommelse.

Alle dataklasser er indkables og nedarver fra en Provider kaldet TAspProvider(indeholder tabel og query component).
Eksempel på nedarvning er

TASPProvider  (alt den tekniske implementering)
    |
TPatientData (alt info vedrørende patienten)

Eksempel på en hvor dan en AdoTable bruges er
Koden er simplificeret

PatientData := TAdoTable.Create(self);
try
  PatientData.Open
  With PatientData do
    begin
      Insert;
      FieldByName('FIRSTNAME').AsString = 'TEST';
      Post;
    end;
Finally
  FreeAndNil(PatientData);
end;

Findes der nogen garbage collection i form af units eller componenter som man kan kompilere ind i programmet - her tænker jeg på 3 rd. parts
Avatar billede martinlind Nybegynder
20. januar 2007 - 11:00 #1
Du kan starte med at lave en close på dit dataset inden du laver en freeandnil, der efter vil jeg anbefale at du læser om hvordan delphi styrer sin mem., løsningen er nok en ny og bedre mem. styring, som du kan skifte ud forholdsvis nemt.
Avatar billede coladrenge Nybegynder
20. januar 2007 - 19:04 #2
Hej

Problemet opstår kun under Windows XP - men ikke hvis man eksempelvis kører direkte på serveren.

Jeg har fundet kommandoen - den sparer for rigtigt meget hukommelse, men jeg har lidt svært ved at se om der er nogle konsekvenser ved at bruge den.


var
  MainHandle : THandle;
begin
  MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID);
  SetProcessWorkingSetSize(MainHandle,DWORD(-1),DWORD(-1));
  CloseHandle(MainHandle);
end;
Avatar billede hrc Mester
21. januar 2007 - 00:58 #3
Jeg har tjekket i VCL'en. En TCustomADODataSet.Destroy laver altid en Close, så martinlind's forslag om at prøve "Close" før "Free", er unødvendigt - heldigvis, for mine programmer er opbygget på samme måde som dine!!

Har du tjekket om det er der det er galt? Tænker på at lave et testprogram der kreerer, bruger og frigiver en TADOTable n antal gange?
Avatar billede coladrenge Nybegynder
21. januar 2007 - 09:38 #4
Hej

Jeg lavede et test program som åbnede en tabel - straks brugte den 32 mb. hukommelse. Brugte jeg nedenstående så brugte den kun efterfølgende 2 mb. og efter et stykketid maks 10 mb. ram.

var
  MainHandle : THandle;
begin
  MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID);
  SetProcessWorkingSetSize(MainHandle,DWORD(-1),DWORD(-1));
  CloseHandle(MainHandle);
end;
Avatar billede coladrenge Nybegynder
21. januar 2007 - 09:39 #5
Hvis jeg laver et test program som opretter og nedlægger en AdoTAble x antal gange så bruger den mere og mere hukommelse. Sjovt nok er problemet kun på Windows XP maskiner.
Avatar billede hrc Mester
21. januar 2007 - 13:27 #6
Det lyder tankevækkende. Er problemet der for TADOQuery; har du prøvet det? Spørger lidt af egen interesse da jeg har et !""!#!" program der skal overgå fra Firebird til MSSQL via ADO.
Avatar billede martinlind Nybegynder
21. januar 2007 - 15:35 #7
hrc >> hvorfor flytte fra firebird ??

Jeg kan anbefale nogle af DelphiMagazine artikler om Delphi Mem. styring, der står også noget om jeres "mirakel kald", kan sku ikke rigtig huske om det havde nogle konsekvenser, mener det ikke, det var vist noget med at Windows rydder lidt op for dig. Men Delphi håndterer ikke mem. forbrug super optimalt i alle tilfælde :(
Avatar billede coladrenge Nybegynder
21. januar 2007 - 19:16 #8
Hej

Jeg har nu lagt den kode ind i programmet som jeg har skrevet om tidligere - umiddelbart så kører det rigtigt godt og programmet bruger nu maks 40 mb. hukommelse. Hvilken er helt iorden når man tænker på det er en MDI app. hvor der er en stor del graffik.

Opret lige et svar begge 2 så får i point
Avatar billede martinlind Nybegynder
21. januar 2007 - 20:02 #9
ok :)
Avatar billede hrc Mester
22. januar 2007 - 08:54 #10
ok ditto.

Martinlind: Vi skifter for at få en ensartet platform - og en som kunderne konservativt foretrækker fremfor Firebird. Desuden har vi en masse administration af language codes, interbase / firebird forskelle, samt et hav af forskellige versioner kørende. Det sidste skyldes at vi skal over på en MSSql. Den største grund er dog at i som bindeled bruger BDE ... Ja, jeg ved det godt! Nej, det fungerer ikke uden problemer!!!

Så, nu hvor programmet skal skrives om, så kan vi ligeså godt skifte platform. Egentlig burde vi også lave programmet Web-baseret, men det har vi desværre hverken kompetancen eller tiden til.
Avatar billede martinlind Nybegynder
22. januar 2007 - 12:57 #11
Hmmm... surt at skulle skifte fra en super fed gratis DB til en MS(skidt) *S*
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester