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 3 von 7     123 45     Letzte »    
Benutzerbild von Sir Rufo
Sir Rufo

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

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 10:40
Ich habe da so eine vage Vermutung, was deinen immensen Speicherbedarf verursacht.

Kannst du mal das Interface von so einem BO zeigen und wie du auf eine Eigenschaft zugreifst?

Ich vermute nämlich, dass du für jede BO Instanz die Eigenschafts-Namen als String im Speicher hast ...
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.343 Beiträge
 
Delphi 11 Alexandria
 
#22

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 11:06
Worauf willst Du raus?

Ich habe z.B.

Delphi-Quellcode:
IMyInf = interface
...
property Name: string read get_Name write set_Name
...
Die Klasse hält dann natürlich noch ein fName: String bzw. ein Objekt, das einen String verwaltet.

Bei Bedarf durchsuche ich eine Liste nach einem Interface mit einem bestimmten Namen. Wenn das einmal gefunden ist arbeite ich nur noch direkt mit dem Interface.

Beziehungen zwischen Objekten/Interfaces werden nicht über Namen-Strings abgebildet.

Ich kann gern mal einen Auszug raussuchen, aber es wäre gut zu wissen, wo Du ein Problem vermutest...
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
 
#23

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 11:22
Ich vermute, dass genau diese Strings, die den Namen für was auch immer definieren, dir den Speicher vollmüllen.

Das kann ich aber erst sehen, wenn ich sehe, wie du denn mit diesen Namen in deinem BO umgehst
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 BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#24

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 11:36
Im Prinzip: Hast du Strings (außer einem eindeutigem Namen), die du für jedes BO anlegst?
SirRufo will vermutlich auf so etwas wie Eigenschafts/Spalten-Namen hinaus, die bei vielen Objekten gleich wären.
  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
 
#25

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 11:38
Im Prinzip: Hast du Strings (außer einem eindeutigem Namen), die du für jedes BO anlegst?
SirRufo will vermutlich auf so etwas wie Eigenschafts/Spalten-Namen hinaus, die bei vielen Objekten gleich wären.
Das ist meine Vermutung
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 jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#26

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 11:40
Wie hoch ist denn der Speicherverbrauch (z.B. auch einfach im Taskmanager, muss nicht so genau sein), wenn du die Out-Of-Memory Exception bekommst?

Wir hatten das gleiche Problem und haben daraufhin auf 64-Bit umgestellt, da es bei unserer Anwendung mit Speicher sparen nicht gereicht hätte. Dort konnte man aber einen Riesenunterschied zu dem Out-Of-Memory der Delphi IDE sehen:
Bei uns kam der Speicherverbrauch auf ca. 1,7-1,8 GiB hoch bevor es zum Problem kam.
Bei der Delphi IDE hingegen kommt (vermutlich durch ungünstiges Speichermanagement?) der Fehler schon bei ca. 1 GiB.

Wodurch wir Speicher sparen konnten war z.B. die Verwendung von TDictionary statt TStringList für die Zuordnung zwischen Strings und anderen Daten, da dadurch nur noch ein Hash im Speicher bleibt statt des ganzen Strings.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#27

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 11:52
da dadurch nur noch ein Hash im Speicher bleibt statt des ganzen Strings.
Das halte ich für ein Gerücht: dann müsste die Hash-Funktion ja eindeutig sein und das Dictionary ließe sich nicht aufzählen.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

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

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 12:35
da dadurch nur noch ein Hash im Speicher bleibt statt des ganzen Strings.
Das halte ich für ein Gerücht: dann müsste die Hash-Funktion ja eindeutig sein und das Dictionary ließe sich nicht aufzählen.
Das denke ich auch. Hash-Werte lassen sich ja nicht in einen Ursprungs-String zurück wandeln. Unterschiedliche Strings können den gleichen Hash-Wert haben.

Bei Video2Brain gibt es ein gutes Tutorial zu Datenstrukturen: https://www.video2brain.com/de/video...atenstrukturen
Ist so ein kleiner 3h-Ersatz für ein 3jähriges Studium.
Ich fand es interessant, wenn auch nicht alles ganz neu war.


@jaenicke

Aber ansonsten scheint Euer Problem zu meinem zu passen. Ich muss die Speichergrößen nochmal zusammentragen. Mit und ohne Delphi sowie als Debug und Release. Mache ich mal heute Abend.
Unter 64 Bit gab es die Probleme natürlich nicht. Ich hatte da mal ein paar Mio Mainobjekte versucht. Aber ich will natürlich dennoch das Ganze möglichst optimieren.


@Sir + Bug

Ja, die Richtung kommt schon hin. Eigenschaften von Objekten werden mit Namen bezeichnet (z.B. "FirstName"). Dem wird dann ein Wert zugeordnet (z.B. "Sir").
Wenn es viele Objekte gibt, die eine Eigenschaft "FirstName" haben wird der String häufig verwendet.

Nun hatte ich aber in der Hilfe (http://docwiki.embarcadero.com/RADSt...e/String-Typen) gelesen (oder es so verstanden), dass Delphi "FirstName" nur einmal erzeugt und künftig Referenzen darauf benutzt. Ändert eine Referenz ihren Wert in "Test" wird der Teststring neu angelegt und der RefCounter von "FirstName" reduziert. Gibt es keine Referenz mehr auf "FirstName" wird der Speicherplatz freigegeben. Ist das richtig?

Ich hatte auch schon überlegt (genauer gesagt ist das auch aus einem Projektinternen Grund ernsthafte Absicht ), in den Eigenschaften statt auf einen Namen-String auf ein Namen-Objekt zu verweisen, das einen String enthält. Dann würden nur noch Pointer verbraucht werden und das Namensobjekt könnte beliebig oft referenziert werden.
Wenn die vorherige Annahme mit den String-Referenzen stimmt, würde das aber am Gesamtverbrauch nicht mehr viel ausmachen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (16. Jul 2015 um 14:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von BUG
BUG

Registriert seit: 4. Dez 2003
Ort: Cottbus
2.094 Beiträge
 
#29

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 12:57
Nun hatte ich aber in der Hilfe (http://docwiki.embarcadero.com/RADSt...e/String-Typen) gelesen (oder es so verstanden), dass Delphi "FirstName" nur einmal erzeugt und künftig Referenzen darauf benutzt. Ändert eine Referenz ihren Wert in "Test" wird der Teststring neu angelegt und der RefCounter von "FirstName" reduziert. Gibt es keine Referenz mehr auf "FirstName" wird der Speicherplatz freigegeben. Ist das richtig?
Ja. Aber Achtung: Erzeugst du zweimal dynamisch den gleichen String, belegt der auch zweimal Speicher.
Ich halte es für besser, einen Stringimplementierung zu benutzen, die sicherstellt, dass Strings mit gleichem Inhalt ihren Speicher teilen. Niemand garantiert, das Strings in Delphi für immer Referenz-gezählt bleiben.
  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
 
#30

AW: Maßnahmen zum Speicherverbrauch minimieren

  Alt 16. Jul 2015, 13:26
@stahli

Deine Annahme mit der String-Speicherverwaltung ist leider nicht korrekt, wie dir diese kleine Anwendung zeigen wird, wenn du dabei den Task-Manager beobachtest.

Hier wird auch immer der gleiche String-Wert zugewiesen, aber auf unterschiedliche Art und Weise mit eben einer unterschiedlichen Speicherauslastung, obwohl effektiv gesehen in allen Instanzen, der gleiche Wert enthalten ist.
Delphi-Quellcode:
unit Form.MainForm;

interface

uses
  System.Generics.Collections,
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TFoo = class
  private
    FValue: string;
  public
    property Value: string read FValue write FValue;
  end;

  TForm1 = class( TForm )
    Timer1: TTimer;
    TimerEnabledCheckBox: TCheckBox;
    FillCachedValuePropertyCheckBox: TCheckBox;
    procedure TimerEnabledCheckBoxClick( Sender: TObject );
    procedure Timer1Timer( Sender: TObject );
    procedure FormShow( Sender: TObject );
    procedure FormActivate( Sender: TObject );
    procedure FillCachedValuePropertyCheckBoxClick( Sender: TObject );
  private
    FValue: string;
    FFooList: TObjectList<TFoo>;
    function GenerateValue: string;
    function GetValue: string;
    procedure PresentValues;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
  end;

var
  Form1: TForm1;

implementation

uses
  System.StrUtils;

{$R *.dfm}
{ TForm1 }

procedure TForm1.AfterConstruction;
begin
  inherited;
  FFooList := TObjectList<TFoo>.Create( True );
  FValue := GenerateValue;
end;

procedure TForm1.BeforeDestruction;
begin
  FreeAndNil( FFooList );
  inherited;
end;

procedure TForm1.TimerEnabledCheckBoxClick( Sender: TObject );
begin
  Timer1.Enabled := TimerEnabledCheckBox.Checked;
end;

procedure TForm1.FillCachedValuePropertyCheckBoxClick( Sender: TObject );
begin
  FFooList.Clear;
  PresentValues;
end;

procedure TForm1.FormActivate( Sender: TObject );
begin
  PresentValues;
end;

procedure TForm1.FormShow( Sender: TObject );
begin
  PresentValues;
end;

function TForm1.GenerateValue: string;
begin
  Result := DupeString( 'Test', 1000 );
end;

function TForm1.GetValue: string;
begin
  if FillCachedValuePropertyCheckBox.Checked then
    Result := FValue
  else
    Result := GenerateValue;
end;

procedure TForm1.PresentValues;
begin
  TimerEnabledCheckBox.Checked := Timer1.Enabled;
  TimerEnabledCheckBox.Caption := string.Format( 'FFooList.Count = %d', [ FFooList.Count ] );
end;

procedure TForm1.Timer1Timer( Sender: TObject );
var
  LFoo: TFoo;
  LIdx: Integer;
begin
  for LIdx := 1 to 100 do
  begin
    LFoo := TFoo.Create;
    try
      LFoo.Value := GetValue;
      FFooList.Add( LFoo );
      LFoo := nil;
    finally
      LFoo.Free;
    end;
  end;
  PresentValues;
end;

end.
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
Antwort Antwort
Seite 3 von 7     123 45     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 07:59 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