AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Maßnahmen zum Speicherverbrauch minimieren

Ein Thema von stahli · begonnen am 15. Jul 2015 · letzter Beitrag vom 23. Jul 2015
Antwort Antwort
Seite 1 von 7  1 23     Letzte »    
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#1

Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 12:02
Ich entwickle unter XE3 (VCL) ein Projekt, das viele dynamische Objekte mit unterschiedlichen Eigenschaften erzeugt (zum großen Teil verschachtelte Listen als Untereigenschaften).

Listen sind z.B. TList<IMyInterface> und TList<IMyNamedObject> sowie einige TStringLists.
Die NamedObjekte haben eine Eigenschaft Name, die letztlich einen String enthält.

Jedes Businessobjekt hat Listen als Eigenschaften, die wieder unterschiedliche Unterobjekte bzw. Interfaces verwalten.

Aktuell kann ich in einer 32bit-Anwendung unter Debugging knapp 100.000 Businessobjekte erzeugen, bis ich ein out of Memory erhalte.

Welche Maßnahmen wären sinnvoll, den Speicherbedarf der Anwendung runter zu schrauben (sowohl den der Anwendung selbst als auch den der Businessobjekte)?


Aktuell benutze ich einfach String für die Speicherung der Businessobjekt-Namen. Das werde ich auf Ansistring oder Shortstring umstellen können.

Macht es Sinn, auf generische Listen (und TComparer) zu verzichten? Generisch verwende ich nur Listen in der Anwendung und könnte auch auf einfache Listen umstellen (dadurch wären ja nur einige Castings mehr notwendig).

Die neue RTTI brauche ich nicht. Spart das Speicherplatz, wenn man die deaktiviert? Was kann man sonst noch deaktivieren?

Eine Datenbankanbindung und auch eine 64bit-Version ist natürlich auch vorgesehen, dennoch möchte ich den Speicherverbrauch der Anwendung nach Möglichkeit drosseln.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 12:29
Die von dir angesprochenen Lösungen verlagern das Problem aber nur ein Stück weiter nach hinten. Dann ist nicht erst bei 100.000 Schluss, sondern bei 150.000 (nur ein geschätztes Beispiel).

Wenn der Speicher-Platz nicht reicht, dann kann man das z.B. mit dem Proxy-Pattern lösen.

Dabei hat man dann nicht mehr das fette BO im SPeicher, sondern eben einen (schmalen) Stellvertreter, der die Daten dann bei Bedarf nachlädt. Möglich wäre auch ein entsprechendes Caching der Daten, die nur für eine bestimmte Zeit im Speicher vorgehalten werden und nach einem Zeitpunkt X wieder aus dem SPeicher geräumt werden. Auch das schafft Platz.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.336 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 12:39
Ja, das habe ich mit meinem letzten Satz anzudeuten versucht (mit Datenbankanbindung meinte ich letztlich einen ORM (bzw. Manager falls ich mich doch noch für NoSQL entscheide), der sich auch um die Lebenszeit der Objekte kümmert).

Mich würde aktuell erst einmal interessieren, welche Maßnahmen man versuchen sollte, um auf 150T oder 200T mögliche Objekte zu kommen.

Z.B. eben durch Ersetzen von String durch AnsiString (wo möglich), rausschmeißen von RTTI oder Generics, oder was sonst noch...?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Der schöne Günther

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

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 12:48
Ich bin da kein Profi, aber Dinge wie RTTI sind doch einmalig vielleicht 5MB Binärcode der drin ist oder nicht. Da wächst doch nichts mit jeder zusätzlich erstellten Instanz.

Auch (dumme Frage, aber trotzdem): Ist dein Speicherverbrauch wirklich so hoch dass man an 32-Bit-Grenzen kommt? Nicht dass du einfach nur ein riesiges Feld allokieren willst und so ein großer Block am Stück ist einfach nicht frei.*


Ansonsten: Das ist doch ähnlich wie wenn jemand Millionen an Zeilen in einer Memo darstellen will und sich dann wundert dass irgendwann nichts mehr geht. Wozu brauchst du hundert tausende von den Dingern gleichzeitig im Speicher? Ich würde als erstes schauen dass man mittels lazy-loading wirklich erst dicke Brocken in den Speicher schaufelt wenn es wirklich so weit ist und darauf achten dass es nicht erst bei Anwendungsende wieder freigegeben wird


* Oder kümmert sich Windows da mit irgendwelchen schlauen Paging und MMF-Geschichten drum? Mann, Betriebssysteme war eine der langweiligsten Vorlesungen die ich je hatte. Nicht viel behalten
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.270 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 12:56
Hallo,
die Umstellung auf ShortString bringt wohl gar nichts, wird wohl eher größer:
ein String[50] mit "123" verbraucht mehr Speicher als ein String mit "123".

1.
Ich würde für Tests einfach mal ein BusinessObject mit String und dann mit AnsiString erzeugen,
es nicht freigeben und mit FastMM4 prüfen, wer mehr Speicher verbraucht.

2.
Vielleicht hast du ja ach einfach auch nur ein Speicherleck.

3.
Ausserdem solltest du prüfen, ob du wirklich 100.000 Objekte im Speicher haben musst.

4.
Du könntest auch etwa an deiner Datenstruktur verändern, indem globale Objekte nur einmal geladen werden
und die anderen Objekte direkte Pointer darauf haben.

Unter 32-bit kann man halt "nur" 2 GB Speicher benutzen, mit Tricks 3 GB.


Heiko
Heiko
  Mit Zitat antworten Zitat
HeZa

Registriert seit: 4. Nov 2004
Ort: Dortmund
182 Beiträge
 
Delphi 10 Seattle Professional
 
#6

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 13:19
Hallo Stali,

du kannst deine Objekte einmal darauf hin untersuchen, wieviele Varianten einer Klasse benötigt werden. Vielleicht hast du Objekte, die zwar millionenfach referenziert werden, aber von denen es nur 1000 verschiedene Varianten gibt.

Dann brauchst du für so eine Klasse nur tausend Objekte in einem Pool zu erzeugen und holst daraus die Referenz auf die benötigte Variante über eine Funktion/Factory Methode.

Ich versuche mal ein Beispiel:
Du lädst 100.000 Aufträge mit durchschnittlich 100 Positionen, jede Position hat ein Artikel-Objekt (das vielleicht auch noch sehr umfangreich ist). Dann würdest ein simpler Ansatz 10.000.000 Artikel-Objekte erzeugen und den Positionen zuordnen. Es gibt vielleicht aber nur 10.000 verschieden Artikel. Dann könntest du durch den oben beschriebenen Ansatz 9.990.000 Objekte sparen.

Diesen und auch die Vorschläge Sir Rufo findest Du im Buch
Design Patterns: Entwurfsmuster als Elemente wiederverwendbarer objektorientierter Software
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
157 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 13:22
Mich würde aktuell erst einmal interessieren, welche Maßnahmen man versuchen sollte, um auf 150T oder 200T mögliche Objekte zu kommen.

Z.B. eben durch Ersetzen von String durch AnsiString (wo möglich), rausschmeißen von RTTI oder Generics, oder was sonst noch...?
Zum einen könntest Du nachsehen ob es in deinem Objekt lineare Abhängigkeiten gibt, also Eigenschaften die sich aus anderen Eigenschaften errechnen lassen. Auf diese Eigenschaften könntest Du verzichten.

Dann wäre es eine Überlegung ob Du immer das ganze BO im Speicher halten müsstest oder nur einen bestimmten Teil (sozusagen den Primärindex) dann könntest Du dein BO in mehrere Happen aufteilen die je nach Bedarf geladen werden.
Den Zugriff auf nicht geladene Properties müsstest Du dann natürlich über Methoden implementieren und darauf achten das diese nicht! published sind.

Beispiel (aus dem Handgelenk, aber ich denke das Prinzip wird klar )

Code:

type TBOLazyDataType = record
                          a,b,c,d : Double;
     end;

     pBOLazyDataType = ^TBOLazyDataType;

     TBObject = class(TObject)
     private
      FIdentifier : Integer;
      LazyData : pBOLazyDataType;
     protected
       function getLazyDataByIdentifier ( ident : Integer ) : pBOLazyDataType;
       function getLazyA : Double;
       procedure setLazyA(aValue : Double);
     public
       Constructor Create;    
     property
      Lazy_A : Double
        read getLazyA write SetLazyA;
     end;


...

Constructor TBObject.Create;    
begin
 ...
 LazyData := nil;
end;

function TBObject.getLazyA : Double;
begin
 if not Assigned(LazyA) then
    LazyA := getLazyDataByIdentifier(Identifier);
 result := LazyA.A;
end;

procedure TBObject.setLazyA(aValue : Double);
begin
 if not Assigned(LazyA) then
    LazyA := getLazyDataByIdentifier(Identifier);
 LazyA.A := aValue;
end;
Außerdem könntest Du nach dem gleichen Prinzip überlegen ob bestimmte BOs bestimmte Eigenschaften bzw. Werte teilen, das ist häufig bei hyrarchischen Daten der Fall die dann nur einmal tatsächlich vorkommen müssten und ansonsten über eine Referenz abgebildet werden.

Und letztendlich könntest Du einfach mal nachsehen ob die irgendwo eine Implementierung eines Baumes rumliegen hast der nur Teile seines Datenbestandes im Speicher hält, falls so was nicht auf Deiner Platte ist könntest Du ja mal hier nachsehen : http://synopse.info/fossil/wiki?name=Big+Table

cu Ha-Jö

cu Ha-Jö
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.126 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 14:03
die Umstellung auf ShortString bringt wohl gar nichts, wird wohl eher größer:
ein String[50] mit "123" verbraucht mehr Speicher als ein String mit "123".
Wie kommst Du den da rauf?
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.487 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 14:09
die Umstellung auf ShortString bringt wohl gar nichts, wird wohl eher größer:
ein String[50] mit "123" verbraucht mehr Speicher als ein String mit "123".
Wie kommst Du den da rauf?
Vielleicht weil es so ist?
Zitat von DokWiki:
While the length of a ShortString can change dynamically, *its memory is a statically allocated 256 bytes*; the first byte stores the length of the string, and the remaining 255 bytes are available for characters
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.126 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 15. Jul 2015, 14:12
Mich würde aktuell erst einmal interessieren, welche Maßnahmen man versuchen sollte, um auf 150T oder 200T mögliche Objekte zu kommen.
Musst Du die den alle im Speicher halten?

Abgesehen davon ist das doch gar nix oder sind die Objecte so groß?

Sagen wir mal Du nimmst dir 1GB RAM... Und willst da 200.000 Objecte unter bringen...
Dann kann jedes Object 5,2 MB groß sein...

Mavarik
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 7  1 23     Letzte »    


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 02:38 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