Autor Beitrag
Stephan.Woebbeking
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 97



BeitragVerfasst: Di 22.05.12 10:20 
Hallo *,

ich habe in meinen Code mehrere Teile übernommen (müssen), die ähnlich diesem hier aussehen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
    iniFile := TIniFile.Create( ChangeFileExt( ParamStr( 0 ), '.ini' ) );
    try
      if iniFile.ValueExists( 'Configuration''DeviceAutoConnect' ) then begin
        bAutoConnect := iniFile.ReadBool( 'Configuration''DeviceAutoConnect', False );
        if bAutoConnect then begin
          actOnGetDeviceInfo.Execute;
        end;
      end;
    finally
      iniFile.Free;
    end;


Beim Programmstart werden drei von diesen Bereichen durchlaufen und am Ende bekomme ich Speicherlecks; unter anderem 1x, 2x oder 3x TIniFile, die Anzahl variiert dabei für mich weitestgehend ohne Bezug zum Programmlauf. Dabei würde ich denken, das "iniFile.Free" sorgt dafür, dass alles freigegeben wird. Die Zeile "iniFile.Free" wird auch tatsächlich angesprungen.

Wo ist mein Denkfehler?

Danke,
Stephan
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Di 22.05.12 10:33 
Hi,

seltsam... hast Du schon mal versucht die Einstellungen der Ini-Datei zu ändern, dass dieser optionale Code bei bAutoConnect=true nicht ausgeführt wird? Und das bei allen 3 Bereichen?

Grüße
Stephan.Woebbeking Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 97



BeitragVerfasst: Mi 23.05.12 08:14 
Ne, hab ich noch nicht, aber ich weiß auch nicht, ob mir das weiterhilft? Wie gesagt, das "Free" wird auch angesprungen und ich habe die globale Suche verwendet um alle "Create" Stellen zu finden. Der Code dazwischen wird halt auch benötigt... Ich schau's mir mal an, wüsste aber gar nicht, wonach ich suchen muss, wenn das wirklich was ändert...

Moderiert von user profile iconNarses: Beiträge zusammengefasst

Also, den Bereich auszukommentieren ändert nichts an dem Verhalten. Was mir allerdings noch aufgefallen ist: Ich habe drei Bereiche die ein IniFile anlegen, die durchlaufen werden. Aber wenn nichts weiter an Nutzeraktion erfolgt, so gibt es am Ende nur EINE nicht freigegebene Instanz. Die drei Bereiche sehen so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  if not FileIsReadOnly( ParamStr(0) ) then begin
    iniFile := TIniFile.Create( szIniFile );
    try
      if iniFile.ValueExists( 'Configuration''Language' ) then
        nActiveLanguage := iniFile.ReadInteger( 'Configuration''Language'1 )
      else
        iniFile.WriteInteger( 'Configuration''Language', nActiveLanguage );
    finally
      iniFile.Free;
    end;
  end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  if FAppIsStarting then begin
    // Check for device auto connection
    iniFile := TIniFile.Create( ChangeFileExt( ParamStr( 0 ), '.ini' ) );
    try
      if iniFile.ValueExists( 'Configuration''DeviceAutoConnect' ) then begin
        bAutoConnect := iniFile.ReadBool( 'Configuration''DeviceAutoConnect', False );
        if bAutoConnect then begin
          actOnGetDeviceInfo.Execute;
        end;
      end;
    finally
      iniFile.Free;
    end;
  end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
    nConnection := -1;
    iniFile := TIniFile.Create( ChangeFileExt( ParamStr( 0 ), '.ini' ) );
    try
      if iniFile.ValueExists( 'Configuration''Connection' ) then begin
        nConnection := iniFile.ReadInteger( 'Configuration''Connection', -1 );
        if nConnection > 3 then begin
          nConnection := -1;
        end;
      end;
    finally
      iniFile.Free;
    end;


Also einer dieser drei müsste nach meinem Verständnis ein Problem machen, aber welcher? Und warum? Oder, warum verhalten die anderen zwei sich besser? Was machen die anders?

Stephan
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Mi 23.05.12 08:44 
Hi,

user profile iconStephan.Woebbeking hat folgendes geschrieben Zum zitierten Posting springen:
Ne, hab ich noch nicht, aber ich weiß auch nicht, ob mir das weiterhilft?
...

Also einer dieser drei müsste nach meinem Verständnis ein Problem machen, aber welcher? Und warum? Oder, warum verhalten die anderen zwei sich besser? Was machen die anders?



dann tippe ich mit meiner nicht vorhandenen Glaskugel auf die Action die du ausführst. Und vermute dass hier entsprechende Anweisungen ablaufen die dazu führen, dass ein IniFile.create mehrfach ausgeführt wird, aber die Freigabe einmal weniger. Deshalb nochmal die Bitte: mach actOnGetDeviceInfo.Execute; bitte mal weg (auskommentieren) und schau ob das Verhalten weiterhin noch so ist...

Grüße
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19338
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 23.05.12 14:51 
Binde FastMM4 als erste Unit im Projektquelltext (.dpr) ein und aktiviere in der Include-Datei den FullDebugMode. Dann kopierst du die beiliegende DLL in das Verzeichnis deines Programms und führst das aus. Schwupps, schon hast du Stacktraces wo die nicht freigegebenen Instanzen erzeugt wurden. ;-)
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Mi 23.05.12 17:44 
Bei der ersten Prozedur rufst Du ja die Datei (Exe-Datei) selber auf. Welchen Sinn macht das? Denn die Anwendung selber ist ja keine INI-Datei (Text-Datei!)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
  if not FileIsReadOnly( ParamStr(0) ) then begin
    iniFile := TIniFile.Create( szIniFile );
    try
      if iniFile.ValueExists( 'Configuration''Language' ) then
        nActiveLanguage := iniFile.ReadInteger( 'Configuration''Language'1 )
      else
        iniFile.WriteInteger( 'Configuration''Language', nActiveLanguage );
    finally
      iniFile.Free;
    end;
  end;


Paramstr(0) = Name der Anwendung mit Erweiterung und Pfad

Normalerweise ist die Anwendung beim Start als Readonly markiert, wenigstens solange, wie sie geöffnet ist.

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.