Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Timerfunktion: Arbeitsspeicher läuft voll (https://www.delphipraxis.net/114738-timerfunktion-arbeitsspeicher-laeuft-voll.html)

Tod787 30. Mai 2008 11:29


Timerfunktion: Arbeitsspeicher läuft voll
 
Es geht um ein Programm in dem stätig abgefragt wird ob die Netzwerkkarten mit einem Medium verbunden sind oder nicht.

Gelöst habe ich dies mit einer Timer-Prozedur in der Zustand der Karten abgefragt wird.
Das Problem ist nun, dass jetzt mit jedem Zyklus ein weiteres Object erstellt wird und demnach langsam aber sicher der RAM vollläuft.

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
 wmi : variant;
 wmiService : variant;
 nicstatus : variant;
 card : Olevariant;
 cnt : integer;
 Enum: IEnumVariant;
 P : IUnknown;
 F : Cardinal;
 connected : integer;
 status : string;

begin
  ListBox1.clear;
  WMI:=CreateOleObject('WbemScripting.SWbemLocator');
  wmiService := wmi.ConnectServer('.', 'root\wmi');
  nicstatus := wmiService.InstancesOf('MSNdis_MediaConnectStatus');
  p := nicstatus._NewEnum;
  p.QueryInterface(IEnumVariant, Enum);
  for cnt := 0 to nicstatus.Count - 1 do
   begin
     Enum.Next(1, card, F);
     connected := card.NdisMediaConnectStatus;
     if (connected = 0) then
        begin
          Status := 'verbunden';
        end
     else
        begin
          Status := 'nicht verbunden';
        end;
     ListBox1.Items.Add( card.InstanceName + ' : ' + status);
  end;
end;
Habe zwar hier aus dem Forum den Tipp bekommen aber leider komme ich da nicht weiter und den User gibts scheinbar nicht mehr.

Zitat:

Er schrieb folgendes:

Du instanziierst mit
Delphi-Quellcode: markieren
WMI:=CreateOleObject('WbemScripting.SWbemLocator') ;


innerhalb eines Timer ein Objekt; logisch, dass irgendwann der Speicher vollläuft, wenn Du das Objekt nicht wieder zerstörst!

Du hast nun zwei Möglichkeiten:
1.
Du erzeugst die Objektinstanz außerhalb des Timers, und damit nur ein einziges Mal (z.B. beim Erzeugen der Form) und greifst im Timer auf dieses Objekt zu. Beim Zerstören der Form gibst Du das Objekt wieder frei.

2.
Du erzeugst das Objekt wie bisher im Timer, gibst es aber auch dort wieder frei.

Ich weiß nicht genau, was Dein Code tun soll, daher weiß ich nicht, was für Dich das Richtige ist.
Intuitiv würde ich allerdings zu Alternative #1 tendieren.
Der Code sonst funktioniert eigentlich sehr gut.

DeddyH 30. Mai 2008 11:33

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Und was ist an der Aussage unklar?

Luckie 30. Mai 2008 11:34

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Objekte aus Com-Servern gibt man frei, in dem man sie auf nil setzt.

Tod787 30. Mai 2008 12:14

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Mein Problem ist, dass ich noch nicht genau weiß wie ich das anstellen soll. Vielleicht kann mir das ja jemand von euch erklären oder das Zurücksetzen eben einfach in den Code oben einbauen.

DeddyH 30. Mai 2008 12:18

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Schreib mal als letzte Zeile
Delphi-Quellcode:
WMI := Unassigned;
. IIRC ging das bei OLE/COM auf diese Art.

Tod787 30. Mai 2008 12:42

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Delphi-Quellcode:
WMI := Unassigned;
wirkt leider nicht (habs an das Ende der For-Schleife gelegt und beim 2. Versuch danach).

Bei
Delphi-Quellcode:
WMI:=NIL
bekomm ich die Fehlermeldung
Zitat:

[Pascal Fehler] Unit1.pas(86): E2010 Inkompatible Typen: 'Variant' und 'Pointer'
Der Arbeitsspeicher nimmt weiterhin mit jedem Zyklus stetig zu :(

FAlter 30. Mai 2008 12:43

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Hi,

evtl. Null?

Keine Ahnung, nur so geraten.

Mfg
FAlter

DeddyH 30. Mai 2008 12:44

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Dann mach doch WMI zu einer globalen Variablen, initialisiere sie im initialization-Abschnitt und gib sie im finalization-Abschnitt wieder frei.

Tyrael Y. 30. Mai 2008 13:09

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Probier mal das...

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
var
 wmi : OleVariant; // <----
 wmiService : variant;
 nicstatus : Olevariant;    //  <----
 card : Olevariant;
 cnt : integer;
 Enum: IEnumVariant;
 P : IUnknown;
 F : Cardinal;
 connected : integer;
 status : string;

begin
  ListBox1.clear;
  WMI:=CreateOleObject('WbemScripting.SWbemLocator');
  try // <----
    wmiService := wmi.ConnectServer('.', 'root\wmi');
    nicstatus := wmiService.InstancesOf('MSNdis_MediaConnectStatus');
    try                //  <----
      p := nicstatus._NewEnum;
      p.QueryInterface(IEnumVariant, Enum);
      for cnt := 0 to nicstatus.Count - 1 do
       begin
         Enum.Next(1, card, F);
         try
           connected := card.NdisMediaConnectStatus;
           if (connected = 0) then
              begin
                Status := 'verbunden';
              end
           else
              begin
                Status := 'nicht verbunden';
              end;
           ListBox1.Items.Add( card.InstanceName + ' : ' + status);
         finally
           card := unassigned;
         end;
       end;
    finally       //  <----
      nicstatus := unassigned;  //  <----
    end;                 //  <----
  finally                //  <----
    wmi := unassigned;   //  <----
  end;                   //  <---- 
end;

Edit: Hab es gerade mal ausprobiert, bei mir bleibt der Arbeitsspeicher stabil.

Tod787 30. Mai 2008 13:56

Re: Timerfunktion: Arbeitsspeicher läuft voll
 
Funktioniert sogar sehr gut :)

Kann aber alles noch nicht ganz nachvollziehen. Jedenfalls hast du mit den Try-Finally-Blöcken im Fehlerfall sämtliche Systemressourcen freigegeben.
Werde mir das übers WE nochmal zu Gemüte führen und dann hoffentlich ein wenig mehr durchblicken. In jedem Fall danke für die schnelle Hilfe.

Schönes WE!


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:45 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz