Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Generics / Speicherprobleme in der IDE (https://www.delphipraxis.net/184811-generics-speicherprobleme-der-ide.html)

ventiseis 23. Apr 2015 09:24

Delphi-Version: XE3

Generics / Speicherprobleme in der IDE
 
Hallo,

da bei uns die IDE regelmäßig wg. Speicherproblemen abstürzt, bin ich mal auf die Suche gegangen, warum die DCUs eines Moduls so groß werden.

Hauptgrund scheint zu sein, dass durch die Generics unser Objektmodell zu umfangreich wird (größte DCU: 14MB). Nach einer Analyse mit MapFileStats (http://www.delphitools.info/other-tools/mapfilestats/) wird der meiste Platz offensichtlich dadurch verbraucht, dass generische Typen (z.B. Listen) immer wieder neu "kopiert" werden, obwohl die Implementierung für normale Objekte eigentlich identisch sein müsste.

Jetzt nun die Frage, gibt es irgendeine Möglichkeit / Strategie, dieses Dilemma zu umgehen? Sollte man wieder eigene Collectionklassen schreiben (oder für jeden Typ eine Ableitung von TCollection erzeugen)? Wie seid ihr mit dem Problem umgegangen?

Einerseits möchte man ja die Typsicherheit von generischen Listen behalten, andererseits nützt die einem auch nix mehr, wenn man nach jedem Compilieren Delphi neu starten muss.

PS: Die üblichen Einstellmöglichkeiten (Projektoptionen) haben wir schon durchprobiert. Und ja, wir verwenden RTTI im Objektmodell. Und wir kompilieren Debug-Infos mit ein, damit im Fehlerfall Zeilennummern mit ausgegeben werden. Laufzeitpackages sind auch aktiv, allerdings nur für die gängigen Delphi-Packages (vcl,rtl, ..).

Uwe Raabe 23. Apr 2015 09:39

AW: Generics / Speicherprobleme in der IDE
 
Die aktuelle Implementierung der Generic ist in Bezug auf den Speicherverbrauch sicher noch verbesserungsfähig. Eine geschicktere Implementierung für Collections findest du allerdings im Spring4D-Framework.

quaero 23. Apr 2015 11:46

AW: Generics / Speicherprobleme in der IDE
 
Mehrfach vorkommende Typen und Typen, die als Parameter genutzt werden, nur einmal pro Projekt definieren und dann diesen Typ verwenden:

Delphi-Quellcode:
TMyIntList = TList<Integer>;

TMeinObject = class
  FIrgendeineListe: TMyIntList
  procedure tueWas(const liste: TMyIntList);
...
Dann muss dieser Typ nur einmal ins Objektmodell.

Stevie 23. Apr 2015 17:02

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1298863)
Die aktuelle Implementierung der Generic ist in Bezug auf den Speicherverbrauch sicher noch verbesserungsfähig. Eine geschicktere Implementierung für Collections findest du allerdings im Spring4D-Framework.

Jaaa, allerdings erst ab der noch zu releasenden 1.2 oder dem aktuellen develop Stand.

Hintergrund Info, wie das gelingt:
Da die Spring4D Collection Types alle über Interfaces geregelt sind, kann man hinter eine IList<TKunde> "einfach" eine TObjectList<TObject> hängen. Das geht aber nunmal bei puren klassenbasierten generischen Listentypen nicht (und nein, auch die verzweifelten Versuche in XE8 ändern da nix dran).

Zitat:

Zitat von quaero (Beitrag 1298924)
Mehrfach vorkommende Typen und Typen, die als Parameter genutzt werden, nur einmal pro Projekt definieren und dann diesen Typ verwenden:

Delphi-Quellcode:
TMyIntList = TList<Integer>;

TMeinObject = class
  FIrgendeineListe: TMyIntList
  procedure tueWas(const liste: TMyIntList);
...
Dann muss dieser Typ nur einmal ins Objektmodell.

Dass dieser Irrglaube immer noch herumgeistert... Nein, nein, nein. Der Compiler bekommt das schon mindestens sein XE (glaube sogar schon mit Delphi 2010) hin, dass er nur einmal eine TList<Integer> baut, egal an wie vielen Stellen ich sie einsetze. Allerdings bekommt er es nicht hin, dasselbe zu tun, wenn ich eine TList<TKunde>, TList<TRechnung>, TList<TBestellung> habe, weil der generische Typparameter immer ein anderer ist, auch wenn der generierte binärcode bis auf das letzte Byte identisch ist.

Der schöne Günther 23. Apr 2015 17:37

AW: Generics / Speicherprobleme in der IDE
 
Das macht den erzeugten Code größer, klar. Aber das soll eine Ursache für das "Out of Memory"-Problem in der IDE sein?

Stevie 23. Apr 2015 17:45

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1298976)
Das macht den erzeugten Code größer, klar. Aber das soll eine Ursache für das "Out of Memory"-Problem in der IDE sein?

Soweit ich weiß, ist das eine Mitursache, da diverse Dinge in der IDE gecached werden, und je mehr da gecached wird, desto mehr Speicher.
Aber genau kann das glaub ich, Andreas beantworten.

ventiseis 23. Apr 2015 19:11

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1298976)
Das macht den erzeugten Code größer, klar. Aber das soll eine Ursache für das "Out of Memory"-Problem in der IDE sein?

Ich gehe schon davon aus, dass dies bei unseren Projekten der Fall ist. In älteren Projekten (mit nicht-generischen Objektmodellen) tritt die IDE-Problematik viel seltener auf.

ventiseis 23. Apr 2015 19:16

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Stevie (Beitrag 1298970)
Da die Spring4D Collection Types alle über Interfaces geregelt sind, kann man hinter eine IList<TKunde> "einfach" eine TObjectList<TObject> hängen. Das geht aber nunmal bei puren klassenbasierten generischen Listentypen nicht (und nein, auch die verzweifelten Versuche in XE8 ändern da nix dran).

Danke für den Tipp! Vielleicht lässt sich hier eine "Idee" übernehmen.

DualCoreCpu 23. Apr 2015 19:17

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1298863)
Die aktuelle Implementierung der Generic ist in Bezug auf den Speicherverbrauch sicher noch verbesserungsfähig. Eine geschicktere Implementierung für Collections findest du allerdings im Spring4D-Framework.

Ich war soeben auf der Webseite, kann dort aber nichts erfahren zu den Lizenzbedingungen. Habe hier einen Altrechner mit Firefox 2.0.0.20. Das sag ich nur, falls die Seite diesen Browser nicht mehr unterstützt.

Wie sind die Konditionen? (Freeware, OpenSource, Shareware, zeitlich begrenzte Testversion, ... )

ventiseis 23. Apr 2015 19:28

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von quaero (Beitrag 1298924)
Mehrfach vorkommende Typen und Typen, die als Parameter genutzt werden, nur einmal pro Projekt definieren und dann diesen Typ verwenden.

Machen wir manchmal, aber nur um die Lesbarkeit des Quelltextes zu verbessern.

Beispiel:
Delphi-Quellcode:
TDataCache = TObjectDictionary<string, TList<TData>>

ventiseis 23. Apr 2015 19:31

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von DualCoreCpu (Beitrag 1298986)
Wie sind die Konditionen? (Freeware, OpenSource, Shareware, zeitlich begrenzte Testversion, ... )

Zitat von der Website:
Zitat:

It uses the Apache License 2.0.

jbg 23. Apr 2015 20:30

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat:

Zitat von Stevie (Beitrag 1298970)
Dann muss dieser Typ nur einmal ins Objektmodell.

Dass dieser Irrglaube immer noch herumgeistert...
Jain. Der Compiler instanziert den Generic für jede DCU-Datei wo er deklariert wird. Erst der Linker vereint dann die Generics mit den selben Typen-Parametern (mit einem sehr langsamen Algorithmus => CompilerSpeedPack enthält einen Patch, damit Spring4D um welten schneller kompiliert).

Speicherverbrauch
Der ErrorInsight/Refactoring Parser trägt hier die Hauptschuld. Dieser verbraucht nämlich für DCU Dateien den doppelten Speicherplatz. Er lädt über den Compiler die DCU Dateien von denen er keine PAS Dateien findet (z.B. System.dcu, Controls.dcu, Forms.dcu, ...) und überträgt dann Teile, welche er gerade braucht, in seine eigene .NET Klassenstruktur. Somit hat man die DCU und die .NET Objekte zu den Daten aus der DCU im Speicher.
Trifft der Parser auf einen Generic (DCU oder PAS), dann geht der Speicher Verbrauch erst so richtig los, denn er instanziert den Generic und kopiert dabei sämtliche Typen. Wenn dann auch noch dank Garbage Collector sich niemand Gedanken macht, wo denn diese Generics-.NET Objekte noch referenziert werden, dann bleiben sie eben bis zum Schließen des Projekts im Speicher.

Dass der Compiler durch die ganzen Ändernung und die Generics natürlich auch mehr Speicher für seine Daten braucht, tut dem ganzen natürlich auch nicht wirklich gut.

Und dann kommt noch das Problem dazu, dass DCU Dateien, die von mehreren Projekten innerhalb einer Projektgruppe genutzt werden, nicht einmal, sondern für jedes einzelne Projekt im Speicher liegen. Hat man also 10 Projekte in einer Projektgruppe und kompiliert diese, dann sind da auch 10 System.dcu, SysUtils.dcu usw. im Speicher. Da hatte ich auch schon ein paar Ideen wie ich die vereinen kann, aber leider schreibt der Compiler in den Speicherbereich während des kompilierens Daten rein, womit man den DCU-Block ala XMS-Speicher under DOS austauschen müsste. Die notwendigen Swap-Codestellen lassen sich aber ohne Compiler-Quellcode recht schlecht alle aufspüren. Also bliebe nur ein empierisches Vorgehen mittels VirtualProtect(READONLY)+VectoredExecptionHandler. Dann müssten aber auch alle möglichen Codepfade durchlaufen werden, welche ich sicherlich nicht alle finden würde.

Der schöne Günther 23. Apr 2015 20:44

AW: Generics / Speicherprobleme in der IDE
 
Wahnsinn, das war interessant. :thumb:

Stevie 23. Apr 2015 21:28

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von DualCoreCpu (Beitrag 1298986)
Ich war soeben auf der Webseite, kann dort aber nichts erfahren zu den Lizenzbedingungen. Habe hier einen Altrechner mit Firefox 2.0.0.20. Das sag ich nur, falls die Seite diesen Browser nicht mehr unterstützt.

Wie sind die Konditionen? (Freeware, OpenSource, Shareware, zeitlich begrenzte Testversion, ... )

Keine Ahnung, auf welcher Seite du warst aber so viel Text zu lesen unter dem Spring4D Logo isses echt nicht und da steht alles drin. Oder zeigt er die Seite überhaupt nicht an?

jbg 23. Apr 2015 21:43

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Stevie (Beitrag 1299000)
Oder zeigt er die Seite überhaupt nicht an?

Firefox Version 2.0.0.20. Mit sowas würde ich mich nicht ins Netz trauen. Wann kam der raus? 2006 ?

Stevie 23. Apr 2015 21:47

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von jbg (Beitrag 1299001)
Zitat:

Zitat von Stevie (Beitrag 1299000)
Oder zeigt er die Seite überhaupt nicht an?

Firefox Version 2.0.0.20. Mit sowas würde ich mich nicht ins Netz trauen. Wann kam der raus? 2006 ?

Da steht ja ZWEI als major version... ich hab 20 gelesen :shock: Naja, aber immerhin die DP scheint zu funktionieren. :)

uligerhardt 24. Apr 2015 07:47

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Stevie (Beitrag 1299000)
Keine Ahnung, auf welcher Seite du warst aber so viel Text zu lesen unter dem Spring4D Logo isses echt nicht und da steht alles drin. Oder zeigt er die Seite überhaupt nicht an?

Ich kriege immer eine bitbucket-Werbeseite ("Get Started") angezeigt. Deine Seite taucht bestenfalls vorher kurz im Hintergrund auf. Kann ich das ohne Anmeldung nicht mal kurz checken?:?:

Stevie 24. Apr 2015 08:12

AW: Generics / Speicherprobleme in der IDE
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von uligerhardt (Beitrag 1299034)
Zitat:

Zitat von Stevie (Beitrag 1299000)
Keine Ahnung, auf welcher Seite du warst aber so viel Text zu lesen unter dem Spring4D Logo isses echt nicht und da steht alles drin. Oder zeigt er die Seite überhaupt nicht an?

Ich kriege immer eine bitbucket-Werbeseite ("Get Started") angezeigt. Deine Seite taucht bestenfalls vorher kurz im Hintergrund auf. Kann ich das ohne Anmeldung nicht mal kurz checken?:?:

www.spring4d.org leitet auf https://bitbucket.org/sglienke/spring4d weiter und das zeigt das hier an:

uligerhardt 24. Apr 2015 08:29

AW: Generics / Speicherprobleme in der IDE
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Stevie (Beitrag 1299039)
www.spring4d.org leitet auf https://bitbucket.org/sglienke/spring4d weiter und das zeigt das hier an:

So hätte ich mir das auch vorgestellt. Ich kriege das:
Anhang 43041
- trotz deiner URL in der Adresszeile.

Stevie 24. Apr 2015 08:34

AW: Generics / Speicherprobleme in der IDE
 
Dann vergleich doch mal die url in deiner Addressleiste mit dem Link den ich im Post zuvor schrieb, ich geb dir nen Tip: RAUTE! :stupid:

uligerhardt 24. Apr 2015 08:47

AW: Generics / Speicherprobleme in der IDE
 
Zitat:

Zitat von Stevie (Beitrag 1299045)
Dann vergleich doch mal die url in deiner Addressleiste mit dem Link den ich im Post zuvor schrieb, ich geb dir nen Tip: RAUTE! :stupid:

Die Raute kommt von alleine. Ich kann sie auch händisch aus der Adresszeile rauspfriemeln - ich sehe dann kurz deine Seite, dann kommt die Raute wieder. :mrgreen:
Liegt vielleicht an dem Uralt-IE in der Arbeit.

ventiseis 29. Apr 2015 07:45

AW: Generics / Speicherprobleme in der IDE
 
[QUOTE=jbg;1298993][quote]
Zitat:

Zitat von Stevie (Beitrag 1298970)
Der ErrorInsight/Refactoring Parser trägt hier die Hauptschuld. Dieser verbraucht nämlich für DCU Dateien den doppelten Speicherplatz.

Kann man das eigentlich irgendwie deaktivieren? Unter
Code:
Tools > Optionen > Code Insight
habe ich alle Checkboxen deaktiviert. Trotzdem bekomme ich über Strg + Leertaste noch eine "Programmierhilfe" und auch mit Strg + Shift + Leertaste werden die Parameterinfos angezeigt. Daher gehe ich davon aus, dass CodeInsight trotzdem läuft.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:54 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