![]() |
Kann das Speicherleck nicht finden...
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ich habe ein Programm geschrieben, das IPs anpingt. Für jeden Ping wird ein Thread erstellt. Ich stelle jedoch fest, dass bei jeder Threaderstellung und Terminierung 16 kByte verloren gehen. Ich kann jedoch nicht nachvollziehen, wo das Speicherleck ist. Hier der Aufruf des Threads...
Delphi-Quellcode:
So wird der Thread dann geschlossen...
IpWatchList[nowIPIndex].IPThread := TMyThreads.Create(true);
IpWatchList[nowIPIndex].IPThread.InetAddress := png_IP; IpWatchList[nowIPIndex].IPThread.TimeOut := settings.TimeOut; IpWatchList[nowIPIndex].IPThread.Index := nowIPIndex; IpWatchList[nowIPIndex].IPThread.Resume;
Delphi-Quellcode:
Nach Terminate wird auch Speicher freigegeben. Jedoch weniger als zuvor reserviert wurde.
procedure TForm1.UpdateIPView(Online : Boolean; Index : Integer);
begin //IpWatchList[Index].IPThread.FreeOnTerminate := true; IpWatchList[Index].IPThread.Terminate; if Online then begin //... end else begin //... end; end; Im Thread geschieht folgendes...
Delphi-Quellcode:
Zum Pingen benutze ich die Unit "raw_ping".
procedure TMyThreads.Execute;
begin Online := Ping(InetAddress,TimeOut); UpdateMain; end; function TMyThreads.Ping(IPAddress : string; IPTimeOut : Integer) : boolean; var Handle : THandle; InAddr : IPAddr; DW : DWORD; rep : array[1..128] of byte; begin Result := false; Handle := IcmpCreateFile; if Handle = INVALID_HANDLE_VALUE then Exit; TranslateStringToTInAddr(InetAddress, InAddr); DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, TimeOut); Result := (DW <> 0); IcmpCloseHandle(Handle); end; procedure TMyThreads.UpdateMain; begin Form1.UpdateIPView(Online,Index); end; Vielen Dank schonmal für eure Hilfe :). |
Re: Kann das Speicherleck nicht finden...
Soo, habe das Leck jetzt einschränken können. Es befindet sich eindeutig in der Ping-Funktion. Wenn ich diese aus dem Programm entferne, verschwindet das Leck.
Also scheint hier irgendwo in der "raw_ping.pas" etwas nicht ganz sauber freigegeben zu werden...
Delphi-Quellcode:
Die Unit enthält natürlich noch ein paar andere Funktionen, in denen sich das Leck befinden könnte.
function Ping(InetAddress : string; TimeOut : Integer) : boolean;
var Handle : THandle; InAddr : IPAddr; DW : DWORD; rep : array[1..128] of byte; begin result := false; Handle := IcmpCreateFile; if Handle = INVALID_HANDLE_VALUE then Exit; TranslateStringToTInAddr(InetAddress, InAddr); DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0); Result := (DW <> 0); IcmpCloseHandle(Handle); end; Ich hoffe, ich befinde mich jetzt nicht auf der falschen Fährte ;). Über Hinweise würde ich mich sehr freuen :) |
Re: Kann das Speicherleck nicht finden...
Moin BenTech,
wie sieht denn TranslateStringToTInAddr aus? |
Re: Kann das Speicherleck nicht finden...
Hi,
hier die Prozedur...
Delphi-Quellcode:
Zum besseren Verständnis hier noch der Header der Unit...
procedure TranslateStringToTInAddr(AIP: string; var AInAddr);
var phe: PHostEnt; pac: PChar; GInitData: TWSAData; begin WSAStartup($101, GInitData); try phe := GetHostByName(PChar(AIP)); if Assigned(phe) then begin pac := phe^.h_addr_list^; if Assigned(pac) then begin with TIPAddr(AInAddr).S_un_b do begin s_b1 := Byte(pac[0]); s_b2 := Byte(pac[1]); s_b3 := Byte(pac[2]); s_b4 := Byte(pac[3]); end; end else begin raise Exception.Create('Error getting IP from HostName'); end; end else begin raise Exception.Create('Error getting HostName'); end; except FillChar(AInAddr, SizeOf(AInAddr), #0); end; WSACleanup; end;
Delphi-Quellcode:
unit raw_ping;
interface uses Windows, SysUtils, Classes; type TSunB = packed record s_b1, s_b2, s_b3, s_b4: byte; end; TSunW = packed record s_w1, s_w2: word; end; PIPAddr = ^TIPAddr; TIPAddr = record case integer of 0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: longword); end; IPAddr = TIPAddr; function IcmpCreateFile : THandle; stdcall; external 'icmp.dll'; function IcmpCloseHandle (icmpHandle : THandle) : boolean; stdcall; external 'icmp.dll' function IcmpSendEcho (IcmpHandle : THandle; DestinationAddress : IPAddr; RequestData : Pointer; RequestSize : Smallint; RequestOptions : pointer; ReplyBuffer : Pointer; ReplySize : DWORD; Timeout : DWORD) : DWORD; stdcall; external 'icmp.dll'; |
Re: Kann das Speicherleck nicht finden...
Habe das Problem aus lauter Verzweiflung jetzt folgendermaßen "gelöst"...
Delphi-Quellcode:
Ich verhindere, dass der Thread terminiert, indem ich eine Endlosschleife hineinpacke. Ausgeführt wird der Ping nur, wenn "paused" false ist. Nach der Schleife habe ich ein Sleep eingebaut, damit die CPU nicht unnötig belastet wird.
procedure TMyThreads.Execute;
begin Repeat if not paused then begin Online := Ping(InetAddress,TimeOut); Synchronize(UpdateMain); end; Sleep(300); Until Terminated; end; Jetzt tritt das Leck nichtmehr auf, da die Threads bestehen bleiben. Falls jemand eine elegantere Lösung haben sollte, oder wenn jemand das Speicherleck doch noch finden sollte, wäre ich natürlich sehr dankbar ;) Ansonsten wünsche ich noch einen guten Rutsch ins neue Jahr :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz