Entwickler-Ecke
Programmierwerkzeuge - [Lazarus/FPC] neue Speicherverwaltung
Bergmann89 - So 30.10.11 21:28
Titel: [Lazarus/FPC] neue Speicherverwaltung
Hey,
ich entwickle zur Zeit sehr viel mit Lazarus/FPC und bin nun auf der Suche nach einer neuen Speicherverwaltung. Für Delhi hatte ich da immer FastMM benutzt, aber das funktioniert unter Lazarus leider nicht so wie es soll. Hauptsächlich suche ich etwas, das mich auf Memoryleaks oder nicht freigegebenen Speicher aufmerksam macht. Hat jmd ne Idee, was ich da nutzen kann?
MfG & Thx Bergmann.
jaenicke - So 30.10.11 23:50
Kompiliere einfach mit dem Flag -gh, dann bekommst du Memory Leaks angezeigt.
Bergmann89 - Mo 31.10.11 07:30
Hey,
danke funktioniert. Leider hab ich schon die ersten Leaks drin :( Aber Ich find die Stellen ich Code nicht. Es sind 3 sehr simple Klassen, die voneinander erben. Und da sind irgendwo 2 Blöcke drin, die nicht freigegeben werden. Ich hab grad mal die Konstruktoren und Destruktoren miteinander verglichen, da wird immer genau das freigegeben, was ich voher erstellt hab. Und zwischendrin wird nie was erzeugt.
Ich benutz da generische Listen, kann es sein, das die nen Fehler haben? Hier ma die Klasse um die es geht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| TglModelNode = class; TglModelNodeList = specialize TFPGObjectList<TglModelNode>;
TglRotationData = record Axis: TgluVector3f; RotSpeed: Single; end;
TglModelNode = class(TglRenderObject) private fChildren: TglModelNodeList; fRotationData: TglRotationData;
function GetCount: Integer; function GetChildren(Index: Integer): TglModelNode; public property Count: Integer read GetCount; property Children[Index: Integer]: TglModelNode read GetChildren; default;
function AddChild: TglModelNode; procedure DelChild(aIndex: Integer); procedure Clear;
procedure Render; procedure Progress(const DeltaTime: Single);
constructor Create; destructor Destroy; override; end; |
Wenn ich fChildren hier nicht erzeuge, dann ist ein ein Block weniger, der vermisst wird. Den anderen find ich aber nicht. In den Elternklassen gibt es auch keine Objekte, da liegen nur n paar Vektoren, Matirzen und Records:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| TglObject = class(TObject) private function GetMatrixPtr: Pointer; protected fPosition: TgluMatrix4f; public property MatrixPtr: Pointer read GetMatrixPtr; constructor Create; end;
TglRenderObject = class(TglObject) private fMesh: TglMesh; fColor: TgluVector4f; fFrontMaterial, fBackMaterial: TglMaterial; fTextureID, fNormalMapID: Cardinal; fTexture, fNormalMap: TglBitmap2D;
function GetMeshID: Cardinal; procedure SetMeshID(aMeshID: Cardinal); function GetFrontMatID: Cardinal; procedure SetFrontMatID(aMaterialID: Cardinal); function GetBackMatID: Cardinal; procedure SetBackMatID(aMaterialID: Cardinal); procedure SetTextureID(aTextureID: Cardinal); procedure SetNormalMapID(aTextureID: Cardinal); public property MeshID : Cardinal read GetMeshID write SetMeshID; property FrontMaterialID: Cardinal read GetFrontMatID write SetFrontMatID; property BackMaterialID : Cardinal read GetBackMatID write SetBackMatID; property TextureID : Cardinal read fTextureID write SetTextureID; property NormalMapID : Cardinal read fNormalMapID write SetNormalMapID;
procedure Render;
constructor Create; destructor Destroy; override; end; |
Ich bin grad echt ratlos :(
MfG & Thx Bergmann.
jaenicke - Mo 31.10.11 08:14
Lassen sich die Quelltexte nicht zufällig mit Delphi kompilieren (halt mit ein paar Syntaxvereinfachungen wegen den in Lazarus etwas umständlicheren Generics, aber das geht ja per IFDEF)?
Da sieht man ja genauer wo die Leaks herkommen (soweit ich mich an die Ausgabe von Lazarus erinnere), wenn es die denn auch mit Delphi gibt.
Ansonsten bleibt dir nur die einzelnen Klassen einzeln zu testen. Wenn du da ein kleines Testprogramm hättest, könnte ich das auch mal anschauen.
Delphi-Laie - Mo 31.10.11 12:19
jaenicke hat folgendes geschrieben : |
Kompiliere einfach mit dem Flag -gh, dann bekommst du Memory Leaks angezeigt. |
Mal eine ganz dumme Frage: Wie kann man dem Compiler ein solches Flag unterjubeln?
Teekeks - Mo 31.10.11 12:28
Diesen in "Projekt → Projekteinstellungen → Compilereinstellungen → Linken → Heaptrc Unit einbinden"
Man kann aber glaube ich auch diese Unit einfach manuell einbinden (als allererstes).
Delphi-Laie - Mo 31.10.11 15:09
Teekeks hat folgendes geschrieben : |
Diesen in "Projekt → Projekteinstellungen → Compilereinstellungen → Linken → Heaptrc Unit einbinden" |
Die Compilereinstellungen sind zwar direkt unter "Projekt" (und nicht unter Projekteinstellungen) placiert, aber dennoch ein dickes Dankeschön! Ich glaubte, daß man den Compiler über irgendwelche Konsolenfenster aufrfen müßte (was vermutlich auch möglich ist).
Teekeks hat folgendes geschrieben : |
Man kann aber glaube ich auch diese Unit einfach manuell einbinden (als allererstes). |
Aha, es wird also eine zusätzliche Unit eingebunden. Und was bewirkt die? Fehlermeldungen zur Laufzeit bei Speicherlecks?
Teekeks - Mo 31.10.11 15:19
Ok, hier unter der 0.9.31 war es unter Projekteinstellungen aber das variiert ja immer auch ein wenig von Version zu Version.
Allgemein werden dann die ganzen Speichernachrichten in die Konsole ausgegeben (u.a. auch welche Blöcke nicht freigegeben wurden).
Was es jedoch genau macht kann ich dir heute Abend aus meinem FreePascal-Buch Zitieren wenn ich wieder daheim bin :)
Delphi-Laie - Mo 31.10.11 15:29
Teekeks hat folgendes geschrieben : |
Ok, hier unter der 0.9.31 war es unter Projekteinstellungen aber das variiert ja immer auch ein wenig von Version zu Version. |
Ist bei mir in der 0.9.28.2er so. Ich wußte nicht, daß das verändert wurde.
Teekeks hat folgendes geschrieben : |
Was es jedoch genau macht kann ich dir heute Abend aus meinem FreePascal-Buch Zitieren wenn ich wieder daheim bin :) |
Naja, wenn es Dir nicht zuviel Mühe macht. Wäre nett, danke!
Bergmann89 - Mo 31.10.11 17:00
Hey,
hab den Fehler. Der ResourcenManager wurde nicht richtig erstellt, und da hat es dann geknallt. Da der Manager aber bis jetzt nicht wirklich genutzt wird, sondern nur rein vorsorglich im Destruktor mit drin steht hab ichd as bis jetzt noch nicht bemerkt. Komischerweiße kahm aber auch keine exception?! Naja jetzt gehts ja ^^
@: Geht doch noch nicht -.- Wenn ich fModel.Destroy aufrufe, dann geht alles 1a. Aber über fModel.Free rennt der debugger eiskalt drüber. Warum?!
MfG & Thx Bergmann.
Teekeks - Mo 31.10.11 22:09
Du musst (wie ich dir ja schon gesagt habe ;) ) ein override hinter die Definition des Destructors werfen :)
jaenicke - Mo 31.10.11 22:50
Das ist ja da. Ein inherited muss aber auch drin stehen. Aber sonst fällt mir auch grad nix ein.
Bergmann89 - Mo 31.10.11 23:03
Hey,
doch Teekeks hat recht. (Er kennt den ganzen Code, da er an dem Projekt mit entwickelt) Zur Erklärung: es gibt ne Klasse TglModel, die ein Objekt der Klasse TglModelNode anlegt. Und beim Model hat beim destruktor das override gefehlt^^
MfG Bergmann.
jaenicke - Mo 31.10.11 23:20
Wirft Lazarus in so einem Fall etwa keine Warnung? Delphi schon...
Teekeks - Di 01.11.11 00:04
Ach weißt du, momentan kommen in diesem Projekt noch so viele Warnungen dass man diese eine total leicht übersehen kann :)
Boldar - Di 01.11.11 00:42
Ähm... so sehen deine Projekte aus, Jaenicke? Project126, Unit137...
Martok - Di 01.11.11 01:32
Seine Testprojekte fürs Forum schon ;)
jaenicke - Di 01.11.11 06:37
Teekeks hat folgendes geschrieben : |
Ach weißt du, momentan kommen in diesem Projekt noch so viele Warnungen dass man diese eine total leicht übersehen kann :) |
Manche Warnungen sind in älteren Projekten, die ich bearbeite, auch noch vorhanden, aber das sind dann solche wie implizite Typumwandlungen durch die Unicodeumstellung. Diese ist in der Regel unkritisch (anders als eine bedenkliche Typumwandlung :D), so dass ich diese einfach ausgeblendet habe.
Leider kann man AFAIK Warnungen in Lazarus nicht selektiv ausblenden, so dass dir dort wirklich nur übrig bleibt alle zu bearbeiten, auch unkritische, um den Überblick zu haben. Dazu würde ich aber auch raten, auch wenn es erst einmal viel Arbeit sein mag. Aber an Fällen wie diesem merkt man ja, dass es eben lohnt, da es an anderer Stelle Arbeit spart. ;-)
Teekeks - Di 01.11.11 10:17
Die größte Masse ist "Variable xy wird nicht genutzt" weil wir teilweise nur die Klassen als solche ohne Inhalt implementiert haben um an anderen Stellen Arbeiten zu können.
jaenicke - Di 01.11.11 10:32
Projekt --> Compilereinstellungen --> Meldungen, da kann man die Häkchen auch bei Lazarus setzen wie ich mittlerweile kurz nachgeschaut habe. Dann siehst du diese irrelevanten Sachen nicht mehr.
In diesem Fall hier reicht es auch unter Ausführlichkeit das Häkchen bei Notizen zu entfernen, denn das ist für Lazarus nicht einmal ein Hinweis, sondern nur eine Notiz. ;-)
Bergmann89 - Di 01.11.11 17:40
Der Schritt ist geplant, wenn die ganzen Klassen die jetzt stehen ihre Funktion erfüllen und wir dann zum nächsten Entwicklungschritt übergehen^^ [ironie]Ich freu mich jetzt schon auf die arbeit[/ironie] -.-
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!