![]() |
Record New/Dispose resultiert in MemoryLeaks
Ich glaube ich habe irgendwo einen Fehler, finde ihn aber nicht :shock:
Ich rufe eine Testprozedur auf
Delphi-Quellcode:
for i := 0 to 50000 do
TTestUnit.Test(TTest.tdmPostMessage, Form1.Handle, WM_THREAD_MSG, 0, 0, 'TEST STR');
Delphi-Quellcode:
class procedure TTestUnit.Test(Method: TTest; hWnd: Winapi.Windows.hWnd; Msg: UINT; wParam: Winapi.Windows.wParam; lParam: Winapi.Windows.lParam; aString: PChar);
var msgData: PTestData; begin New(msgData); msgData.Msg := Msg; msgData.wParam := wParam; msgData.lParam := lParam; msgData.aString := aString; case Method of tdmSendMessage: SendMessage(hWnd, msgData.Msg, 0, Winapi.Windows.lParam(msgData)); tdmPostMessage: PostMessage(hWnd, msgData.Msg, 0, Winapi.Windows.lParam(msgData)); tdmQueue: ; end; end; {* TTestData = record Msg: UINT; wParam: Winapi.Windows.wParam; lParam: Winapi.Windows.lParam; aString: PChar; end; PTestData = ^TTestData ; *}
Delphi-Quellcode:
Beim Ausschalten des Programms erhalte ich exakt 40001 MemoryLeaks.
type
TForm1... public procedure TTestMessage(var msg: TMessage); message WM_THREAD_MSG; // WM_THREAD_MSG ist WM_USER + 991; implementation procedure TForm1.TTestMessage(var msg: TMessage); var msgData: PTestData; begin msgData := PTestData(msg.lParam); try Caption := PTestData(msg.lParam).aString; finally Dispose(msgData); end; end; |
AW: Record New/Dispose resultiert in MemoryLeaks
// Edit 2:
Hah, jetzt habe ich glaube ich die Ursache: 50.000 mal PostMessage ist zu viel für die Windows Message queue (ist ja auch völlig praxisfern): Zitat:
![]() // Edit: Nö, ich lag falsch. Siehe: ![]() Ab hier bitte nicht weiterlesen -.- Da ich in meiner jahrelangen, glänzenden Karriere als Delphi-Entwickler noch kein einziges mal New oder Dispose verwendet habe bin ich mir nicht sicher, aber: Dispose gibt einfach den Speicher für den Record frei. Dein Record scheint aber mindestens einen gemanagten Typen (String namens "aString") zu enthalten, der wird denke ich nicht vernünftig abgeräumt. Einfach nur der Platz für den Zeiger im Record wird freigegeben, der auf dem Heap angelegte Speicher für den String verbleibt auf ewig als Leiche dort. Ich habe keine Ahnung wie man es richtig macht, spontan hätte ich gedacht statt ![]() ![]() |
AW: Record New/Dispose resultiert in MemoryLeaks
Zitat:
Allerdings wäre die Offenlegung der Deklaration von PTestData sicher nicht schädlich. |
AW: Record New/Dispose resultiert in MemoryLeaks
Entfernen des PChars aus dem Record schafft keine Abhilfe. Finalize vor/statt Dispose aufzurufen leider auch nicht.
Vielleicht hilft es ja. Die Memory Leaks treten nur mit PostMessage auf. Mit SendMessage gibt es keine. Zitat:
|
AW: Record New/Dispose resultiert in MemoryLeaks
Zitat:
Hast du denn mal gezählt, ob wirklich genauso viele Dispose wie New aufgerufen werden? Da PostMessage die Message ja nur in die Message-Queue stellt, könnte es ja sein, daß das Programm beendet wird, bevor die alle abgearbeitet wurden. |
AW: Record New/Dispose resultiert in MemoryLeaks
Ich habe die Deklaration von TTestData auch erst überlesen ;-)
Ich habe meinen Beitrag in der Zwischenzeit noch einmal editiert. Die Windows Message Queue ist 10.000 Einträge groß, da passen natürlich die anderen 40.000 nicht mehr rein. |
AW: Record New/Dispose resultiert in MemoryLeaks
Habe das gerade schnell mit 2 böse, globalen Variablen und einem TTimer geteset.
Es gibt 50000 New() und 10000 Dispose(). |
AW: Record New/Dispose resultiert in MemoryLeaks
Das sollte mittlerweile niemanden mehr überraschen.
|
AW: Record New/Dispose resultiert in MemoryLeaks
Mir kommt das ganze Konstrukt etwas seltsam vor. Da wird ein Pointer lokal definiert, mit seinen Daten wird ein postmessage losgeschickt und dann ist die procedure zu ende
und der Pointer und seine Daten hängen im undefinierten Raum???
Delphi-Quellcode:
Kann ich ja noch nachvollziehen, aber postmessage halte ich für Harakiri.
begin
new(p); sendmessage(p...); dispose(p); Oder bin ich da auf dem falschen Gleis? Gruß K-H |
AW: Record New/Dispose resultiert in MemoryLeaks
Ich verwende absichtlich PostMessage, da ich nicht auf die Antwort warten möchte wie es bei SendMessage wäre.
Einziger Zweck dieses Hin- und Hers mit dem Rercord ist es, dass ich mehr und verschiedene Daten per PostMessage senden können möchte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:29 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-2025 by Thomas Breitkreuz