AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Record New/Dispose resultiert in MemoryLeaks
Thema durchsuchen
Ansicht
Themen-Optionen

Record New/Dispose resultiert in MemoryLeaks

Ein Thema von Glados · begonnen am 7. Nov 2017 · letzter Beitrag vom 8. Nov 2017
Antwort Antwort
Seite 1 von 2  1 2      
Glados
(Gast)

n/a Beiträge
 
#1

Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 22:34
Ich glaube ich habe irgendwo einen Fehler, finde ihn aber nicht

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:
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;
Beim Ausschalten des Programms erhalte ich exakt 40001 MemoryLeaks.

Geändert von Glados ( 7. Nov 2017 um 22:37 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 22:55
// 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:
There is a limit of 10,000 posted messages per message queue.
Quelle: MSDN zu PostMessasge


// Edit: Nö, ich lag falsch.
Siehe: https://stackoverflow.com/q/4285892/2298252

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 Dispose einfach Finalize verwenden. Oder nicht stattdessen, sondern davor? Keine Ahnung. Aber zumindest bei der Ursache könnte ich mir vorstellen richtig zu liegen

Geändert von Der schöne Günther ( 7. Nov 2017 um 23:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#3

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:00
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.
Das ist kein String sondern ein PChar und da wird in der Schleife eine Stringkonstante übergeben.

Allerdings wäre die Offenlegung der Deklaration von PTestData sicher nicht schädlich.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#4

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:00
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:
Allerdings wäre die Offenlegung der Deklaration von PTestData sicher nicht schädlich.
Steht doch oben im ersten Beitrag als Kommentar.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#5

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:04
Steht doch oben im ersten Beitrag als Kommentar.
Sorry, hatte ich überlesen.

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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:06
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.
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#7

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:07
Habe das gerade schnell mit 2 böse, globalen Variablen und einem TTimer geteset.
Es gibt 50000 New() und 10000 Dispose().
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:15
Das sollte mittlerweile niemanden mehr überraschen.
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#9

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:45
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:
begin
  new(p);
  sendmessage(p...);
  dispose(p);
Kann ich ja noch nachvollziehen, aber postmessage halte ich für Harakiri.

Oder bin ich da auf dem falschen Gleis?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Glados
(Gast)

n/a Beiträge
 
#10

AW: Record New/Dispose resultiert in MemoryLeaks

  Alt 7. Nov 2017, 23:47
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.
  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 23:39 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