AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Memory-Leak WMI

Ein Thema von El.Blindo · begonnen am 30. Jan 2007 · letzter Beitrag vom 7. Feb 2007
Antwort Antwort
Seite 1 von 2  1 2      
El.Blindo

Registriert seit: 24. Okt 2006
18 Beiträge
 
#1

Memory-Leak WMI

  Alt 30. Jan 2007, 11:32
Moin,

Ich mache grad die ersten Gehversuche mit WMI. WMI scheint recht nützlich zu sein um an verschiedene Informationen zu kommen.
In meinem Beispiel geht es um Prozesse. Ich weiss zwar das es andere Möglichkeieten gibt an diese Informationen zu kommen z.B. Toolhlp32, aber mir geht es halt darum WMI zu verstehen.

Leider sind meine bisherigen Versuche nicht von erfolg gekrönt, das Ganze funktioniert zwar, aber verursacht Memory-Leaks. Ich habe das ganze soweit verfolgen können das Die Memory-Leaks irgendwie in der WMI entstehen. Denke ich zumindestens.

Aber komme irgendwie nicht zu einer Lösung, irgendwer ne Idee ?

Hier mal der Code :

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, WbemScripting_TLB, ActiveX, StdCtrls, ExtCtrls;


Type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function getWMIProcess : TStringList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function TForm1.getWMIProcess : TStringList;
var
   l_WMILocator: ISWbemLocator;
   l_WMIServices: ISWbemServices;
   l_WMIObjectDefinition: ISWbemObject;
   l_WMIObjectSet: SWbemObjectSet;
   l_WMIObjectInstances: IEnumVariant;
   l_WMIObject: ISWbemObject;
   l_WMIPropertySet: ISWbemPropertySet;
   l_WMIProperty: ISWbemProperty;

   l_TempObj: OleVariant;
   l_ObjValue: Cardinal;

   WMI_Name : String;
   WMI_PID : uint64;
   WMI_Tick : uint64;
   WMI_UTime : uint64;
   WMI_KTime : uint64;
   WMI_Mem : uint64;

begin

   result := TStringList.Create;

   l_WMILocator := CoSWbemLocator.Create;
   l_WMIServices := L_WMILocator.ConnectServer('.', 'root\CIMV2', '', '', '', '', 0, nil);
   l_WMIObjectDefinition := l_WMIServices.Get('Win32_Process', wbemFlagUseAmendedQualifiers, nil);
   l_WMIObjectSet := l_WMIObjectDefinition.Instances_(0, nil);
   l_WMIObjectInstances := (l_WMIObjectSet._NewEnum) as IEnumVariant;

   while (l_WMIObjectInstances.Next(1, l_TempObj, l_ObjValue) = S_OK) do
   begin
      WMI_Tick := GetTickCount;
      l_WMIObject:= IUnknown(l_TempObj) as SWBemObject;

      l_WMIPropertySet := l_WMIObject.Properties_;

      l_WMIProperty := l_WMIPropertySet.Item('Name', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_Name := l_WMIProperty.Get_Value else WMI_Name := 'N/A';

      l_WMIProperty := l_WMIPropertySet.Item('ProcessId', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_PID := l_WMIProperty.Get_Value else WMI_PID := 0;

      l_WMIProperty := l_WMIPropertySet.Item('WorkingSetSize', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_Mem := l_WMIProperty.Get_Value div 1024 else WMI_Mem := 0;

      l_WMIProperty := l_WMIPropertySet.Item('UserModeTime', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_UTime := l_WMIProperty.Get_Value else WMI_UTime := 0;

      l_WMIProperty := l_WMIPropertySet.Item('KernelModeTime', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_KTime := l_WMIProperty.Get_Value else WMI_KTime := 0;

      result.add(IntToStr(WMI_PID) + ' : ' + WMI_Name + ' - ' +
                 IntToStr(WMI_Mem) + ' K ' +
                 InttoStr(WMI_UTime + WMI_KTime));
   end;
   l_WMILocator := nil;
   l_WMIServices := nil;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Memo1.Lines := getWMIProcess;
end;

end.
  Mit Zitat antworten Zitat
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#2

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 12:09
Deine Funktion erzeugt eine TStringList. Aber niemand gibt diese StringList wieder frei => MemoryLeak.
  Mit Zitat antworten Zitat
El.Blindo

Registriert seit: 24. Okt 2006
18 Beiträge
 
#3

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 19:11
Tjo, leuchtet ein, aber irgendwie brauch ich ja die TStringList als Ergebnis der Function.

Aber wie krieg ich den Speicher wieder frei ?

result.free erzeugt ein Exception, das mag er nicht.

Wenn ich mir vorher ein Stringlist erstelle :

Delphi-Quellcode:
function TForm1.WhatEver : TStringList;
var
  StList : TStringList;

Begin
  StList := TStringList.Create; // Erstellen
  try
    blah
    blah
    blah
    StList.add(Result of blah);
  result := StList; // Zuweisen des Ergebnisses an Result
  finally
     StList.Free; // Speicher freigeben
  end;
end;
Dann gibts auch ne Exception!

Confused, scheint nicht so einfach zu sein ne TStringlist als Rückgabewert zu haben.
  Mit Zitat antworten Zitat
Elvis

Registriert seit: 25. Nov 2005
Ort: München
1.909 Beiträge
 
Delphi 2010 Professional
 
#4

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 19:17
Übergib' einfach einen Parameter vom Typen TStrings.
Dadurch kannst du eine StringList reinwerfen oder die items einer ListBox, etc.
Vergesse aber nicht BeGinUpdate am Anfang und EndUpdate am Ende auszuführen.
Sonst wird das schnell sehr lahmarschig wenn jemand die items eines Controls übergibt.
Robert Giesecke
I’m a great believer in “Occam’s Razor,” the principle which says:
“If you say something complicated, I’ll slit your throat.”
  Mit Zitat antworten Zitat
El.Blindo

Registriert seit: 24. Okt 2006
18 Beiträge
 
#5

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 19:19
Öhhh, Bahnhof

Ich doof (oder unwissend). Haste mal nen Bleistift ?
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 19:25
Er meint das so...

Delphi-Quellcode:
procedure TForm1.getWMIProcess(Liste:TStrings);
var
   l_WMILocator: ISWbemLocator;
   l_WMIServices: ISWbemServices;
   l_WMIObjectDefinition: ISWbemObject;
   l_WMIObjectSet: SWbemObjectSet;
   l_WMIObjectInstances: IEnumVariant;
   l_WMIObject: ISWbemObject;
   l_WMIPropertySet: ISWbemPropertySet;
   l_WMIProperty: ISWbemProperty;

   l_TempObj: OleVariant;
   l_ObjValue: Cardinal;

   WMI_Name : String;
   WMI_PID : uint64;
   WMI_Tick : uint64;
   WMI_UTime : uint64;
   WMI_KTime : uint64;
   WMI_Mem : uint64;
begin
   l_WMILocator := CoSWbemLocator.Create;
   l_WMIServices := L_WMILocator.ConnectServer('.', 'root\CIMV2', '', '', '', '', 0, nil);
   l_WMIObjectDefinition := l_WMIServices.Get('Win32_Process', wbemFlagUseAmendedQualifiers, nil);
   l_WMIObjectSet := l_WMIObjectDefinition.Instances_(0, nil);
   l_WMIObjectInstances := (l_WMIObjectSet._NewEnum) as IEnumVariant;

   while (l_WMIObjectInstances.Next(1, l_TempObj, l_ObjValue) = S_OK) do
   begin
      WMI_Tick := GetTickCount;
      l_WMIObject:= IUnknown(l_TempObj) as SWBemObject;

      l_WMIPropertySet := l_WMIObject.Properties_;

      l_WMIProperty := l_WMIPropertySet.Item('Name', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_Name := l_WMIProperty.Get_Value else WMI_Name := 'N/A';

      l_WMIProperty := l_WMIPropertySet.Item('ProcessId', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_PID := l_WMIProperty.Get_Value else WMI_PID := 0;

      l_WMIProperty := l_WMIPropertySet.Item('WorkingSetSize', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_Mem := l_WMIProperty.Get_Value div 1024 else WMI_Mem := 0;

      l_WMIProperty := l_WMIPropertySet.Item('UserModeTime', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_UTime := l_WMIProperty.Get_Value else WMI_UTime := 0;

      l_WMIProperty := l_WMIPropertySet.Item('KernelModeTime', 0);
      if not VarIsNull(l_WMIProperty.Get_Value) then
        WMI_KTime := l_WMIProperty.Get_Value else WMI_KTime := 0;

      Liste.Append(IntToStr(WMI_PID) + ' : ' + WMI_Name + ' - ' +
                   IntToStr(WMI_Mem) + ' K ' +
                   InttoStr(WMI_UTime + WMI_KTime));
   end;
   l_WMILocator := nil;
   l_WMIServices := nil;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  getWMIProcess(Memo1.Lines);
end;
Gruss
Thorsten
  Mit Zitat antworten Zitat
El.Blindo

Registriert seit: 24. Okt 2006
18 Beiträge
 
#7

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 20:23
Habs mal so gemacht, funktionieren tuts immer noch genauso wie am Anfang!
NUR leider ist das Memoryleak immer noch vorhanden.

Kann man ja Wunderbar in der Ausgabe sehen. Der Timer steht auf 250ms.

Speicher beim Start: ca 7700K
Nach 1 Min : ca. 16000K
Nach 2 Min : ca. 30000K

So nach einigen Minuten 80000K

Das sieht nich gut aus!

wtf wenn ich das mal so sagen darf

Achja, aus dem Liste.Append hab ich Liste.add gemacht.

Der Aufruf erfolgt so :

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Memo1.Clear;
  getWMIProcess(Memo1.Lines);
end;
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 20:27
Vielleicht hast du ja noch mehr Speicherprobleme, an anderer Stelle.
Schau dir mal MemProof an, das Programm kann dir auch die Zeile zeigen, in der das Speicherleck entsteht.

Gruss
Thorsten
  Mit Zitat antworten Zitat
El.Blindo

Registriert seit: 24. Okt 2006
18 Beiträge
 
#9

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 20:41
Hab ich schon, der schmeisst 1000 Sachen raus und will immer die System.pas, hab ich nicht.

Zudem besteht mein Programm nur aus dieser einen Funktion, eigentlich recht übersichtlich.
Im Moment komm ich immer mehr zu dem Schluss das der Fehler im WMI liegt und nicht in meiner
Source.

Den, vielmehr als eben WMI aufrufen macht mein Code ja nicht.

Hab das Ganze mal nachvollzogen indem ich die Stringlist rausgeworfen habe und einfach den Speicherbedarf per
Label ausgebe : Label1.Caption := IntToStr(WMI_Mem);

Memory-Leak immer noch vorhanden.
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Memory-Leak WMI

  Alt 30. Jan 2007, 21:02
Ist dann wohl so. Leider kann man deinen Code nicht testen, schade.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:09 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