Hat Pascal Probleme mit der Speicherverwaltung?

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
tryunderror
Beiträge: 57
Registriert: Di 9. Okt 2012, 17:32

Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von tryunderror »

Hat Pascal Probleme mit der Speicherverwaltung?
Ist das richtig
Pascal hat Probleme im Code in der Speicherverwaltung.
Denn wenn ich grosse Datenstrukturen mit Pointern anlege, dann ist die Speicherfreigabe problematisch. Oder ist das falsch bei Freepascal oder TP?






Kann Java es besser?

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von m.fuchs »

Bitte zeige mal ein Beispielprogramm, wo es deiner Meinung nach nicht richtig funktioniert.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

baumina
Beiträge: 152
Registriert: Mo 3. Feb 2014, 14:07
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von baumina »

Dass Pascal Probleme mit der Speicherverwaltung haben soll, ist mir neu. Den Speicher, den man sich im Programm reserviert gibt man wieder frei und alles ist gut. Java baut auf eine automatische Speicherbereinigung (garbage collecton) das kann man evtl. als Vorteil deuten.
.

tryunderror
Beiträge: 57
Registriert: Di 9. Okt 2012, 17:32

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von tryunderror »

m.fuchs hat geschrieben:Bitte zeige mal ein Beispielprogramm, wo es deiner Meinung nach nicht richtig funktioniert.


Nein
Du hast das falsch verstanden.

Also ich programmiere

root=Zeigerauffussballstadion

fussballstadion record
getraenke
zuschauer=array von 1 bis 1000000 aus Person

person= name adresse

Jetzt machst Du den Baum voll mit Millionen von Daten vorher hast Du new gemacht.
Und jetzt machst Du root auf nil.
Und jetzt so heisst es
würde wenn Du in Pascal Zeiger löscht mit den Knoten daran
dass der Compiler das nicht gut verwaltet.

Das hat mit der Theorie von Pascal nichts zu tun.

Oder anders: Wird mit dispose alles sauber gelöscht?

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von m.fuchs »

Du schreibst sehr schwer lesbar. Ich fasse mal zusammen was ich da rauslese. Du reservierst Speicher und lässt einen Zeiger darauf zeigen. Dann setzt du diesen Zeiger auf nil und räumst den reservierten Speicher aber nicht weg.
Dann bleibt der natürlich bestehen und dein RAM läuft voll. Das ist aber kein Problem des Speichermanagers, sondern ein Programmierfehler.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

tryunderror
Beiträge: 57
Registriert: Di 9. Okt 2012, 17:32

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von tryunderror »

Ich frage schlecht. Kein Problem.

Also Du machst ein Programm.
Jetzt wirst Du pausenlos

new machen

nil

und dispose.

Siehe Beispiel. Also Du programmierst eine Liste alle Klassenkameraden. Und wenn nun einer sitzenbleibt wird sein record im Baum gelöscht.
Aber tut das auch der compilierte Code?

baumina
Beiträge: 152
Registriert: Mo 3. Feb 2014, 14:07
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von baumina »

Wie gesagt jeden Speicher, den du reservierst, gibst du danach wieder frei und alles ist gut. In der Zwischenzeit programmiert man weniger mit new und dispose, sondern mehr mit Objekten und Listen, die man mit Create und Free verwaltet.
.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von af0815 »

Pascal hat Gott sei Dank KEINE Garbage Collection.

Das ist der Programmierer selbst für den Müll zuständig.

Also
a) New
b) Verarbeitung
c) Dispose
d) Dann kann man den Pointer nil machen.

In anderen Sprachen wird durch das nil machen ein implizierter Aufruf gemacht um der Speicherverwaltung zu sagen, dam na das Objekt nicht mehr haben will und es ungültig ist. In Pascal wird da nichts herumgetrickst.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von m.fuchs »

tryunderror hat geschrieben:Also Du machst ein Programm.
Jetzt wirst Du pausenlos

new machen

nil

und dispose.

Siehe Beispiel.


Welches Beispiel? Das ist ja was ich meine, zeig einen Beispielcode und man kann dir sagen ob der Speicher auch wieder korrekt freigegeben wird.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von Warf »

Lazarus hat wie bereits erwähnt keine Probleme mit der Speicherverwaltung, sondern man muss sich um die Speicherbelegung selbst kümmern sonst entstehen Speicherlücken (Außer bei Strings und Dynamischen Arrays, die sind Referenzgezählt) mal ein Beispiel:

Code: Alles auswählen

program Test;
{$MODE OBJFPC}{$H+}
uses SysUtils;
type
  PTree = ^TTree;
  TTree = record
    Val: Integer;
    LeftNode, RightNode: PTree;
  end;
// Zufälligen Baum erstellen
function FillTree(Depth: Integer): PTree;
begin
  new(Result);
  Result^.Val := Random(100);
  if Depth >0 Then
  begin
    Result^.LeftNode := FillTree(Depth - 1);
    Result^.RightNode := FillTree(Depth - 1);
  end;
end;
 
//Inorder traversierung ausgeben
procedure PrintTree(r: PTree);
begin
  if Assigned(r^.LeftNode) then
    PrintTree(r^.LeftNode);
  Write(Format(';%d;', [r^.Val]));
  if Assigned(r^. RightNode) then
    PrintTree(r^.RightNode);
end;
 
//Speicher Freigeben
procedure destroyTree(r: PTree);
begin
  if Assigned(r^.LeftNode) then
    destroyTree(r^.LeftNode);
  if Assigned(r^. RightNode) then
    destroyTree(r^.RightNode);
  dispose(r);
end;
 
var root: PTree;
begin
  root:=FillTree(10); // Baum mit tiefe 10 erstellen
  try
    PrintTree(root); //Inorder traversierung ausgeben
  finally
    destroyTree(root); //Speicher freigeben
  end;
end.


Wenn man sich nun nicht um die Speicherfreigabe kümmert (durch destroyTree) hinterlässt man eine Speicherlücke bis das System nach Terminierung des Prozesses den aus dem Speicher wirft.

In Java wird das aufräumen automatisch erledigt durch einen Garbage Collector, ein Programm der JVM welcher alle paar Ticks Anspringt und den Speicher nach solchen Lücken durchsucht und diese beseitigt.

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von Komoluna »

Warf hat geschrieben:In Java wird das aufräumen automatisch erledigt durch einen Garbage Collector, ein Programm der JVM welcher alle paar Ticks Anspringt und den Speicher nach solchen Lücken durchsucht und diese beseitigt.

Ob das jetzt ein Vor/Nachteil ist, darüber lässt sich trefflich streiten, aber ich finde es leichter verständlich, wenn man den belegten Speicher selbst wieder freigeben muss.
Ist ja auch sonst so. Was man irgendwo ausgebreitet hat, muss man auch wieder aufräumen.
Außerdem dürfte es effizienter sein, da man als Programmierer selber weiß, welchen Speicher man noch braucht, und welchen nicht.
Jemand/etwas, das einem hinterherräumt und die ganze Zeit fragt "Brauchst du dies noch? Brauchst du jenes noch?" ist nicht gerade effizient.
(So viel zu meiner persönlichen Meinung)

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

tryunderror
Beiträge: 57
Registriert: Di 9. Okt 2012, 17:32

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von tryunderror »

Danke an Dwarf.
Das meinte ich.
Der User muss selbst putzen.
Frage: Ist das Konzept von Java besser?
Gibt es bessere Speicherverwaltung mit zum Beispiel virtuellem Heap?

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von m.fuchs »

Naja, was heißt "besser"? Ist nicht so einfach zu beantworten. Ich arbeite nicht viel mit Java aber unter anderem mit .NET. Auch dort gibt es einen Garbage Collector.
Sowas kann durchaus von Vorteil, aber nur wenn man Anfänger ist und leicht den Überblick verliert. Dann hat man keinerlei Druck um über die Lebenszeit von reserviertem Speichen nachzudenken.

ABER: Wenn man sich dann doch mal weiterentwickelt, stößt man irgendwann an die Grenzen solcher Automatismen. Ein konkretes Problem hatten wir mit einer Funktion. Plötzlich war der Speicherbedarf bei 800 MiB. Nur für einen Funktionsaufruf. Einfach weil viele, viele String-Objekte erstellt wurden. Kamen wir auch nicht darum herum, weil die Eingangsdaten äußerst dämlich organisiert waren. Kein Problem, also haben wir den Garbage Collector gebeten, immer mal wieder den Speicher aufzuräumen. Das ist zwar etwas langsamer, aber Geschwindigkeit war kein Kriterium. Nur leider ist das Bitten wirklich eine Bitte. Der Collector entscheidet dann selbst, ob er jetzt einen Aufräumdurchlauf macht oder nicht. In diesem Fall wollte er nicht.

Von daher ziehe ich definitiv ein System vor, bei dem ich den Mist den ich erzeuge auch selber wegräume.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von Warf »

Ein Garbage Collector ist schon recht angenehm und funktioniert in Java oder .Net auch problemlos da dieser in dem Virtuellen Prozessor der Sprachen (JVM bzw CLR) implementiert ist. Auch wenn es recht angenehm ist muss man dazu sagen dass es einen Riesigen Overhead erzeugen würde in einer Nativen sprache den Spass zu implementieren (Objective C hat das mal versucht). Bei nativen Sprachen wird eher ein anderer Ansatz verfolgt, die Referenzzählung, die seit C++11 in C++ die Kompletten aufräumarbeiten übernimmt. Dabei zählt eine Variable wie viele Zeiger es auf diesen Speicherbereich gibt. Fällt diese Variable auf 0 so wird der Speicher freigegeben. Das hoch und Runterzählen erfolgt bei jeder Zuweisungsoperation (explizit oder Implizit). Bei dem System bin ich allerdings auch eher skeptisch, da es auch teilweise nicht Funktioniert. Pascal implementiert das z.B. bei Dynamischen Arrays, und hier mal ein Beispiel wo dieses System starke defizite aufweist:

Code: Alles auswählen

program Test;
{$Mode ObjFPC}{$H+}
 
// Aktuelle Referenzzahl eines Arrays
function GetRefCount(a: Pointer): SizeInt;
var p: PSizeInt;
begin
  p:=(a-SizeOf(SizeInt)*2);
  Result:=p^;
end;
 
var a, b, c: Array of Integer;
begin
  SetLength(a, 1); // Array erstellen
  WriteLn(GetRefCount(@a[0])); // 1
  b:=a;
  WriteLn(GetRefCount(@a[0])); // 2
  Move(a, c, SizeOf(c));
  WriteLn(GetRefCount(@a[0])); // 2
  b:=nil;
  WriteLn(GetRefCount(@a[0])); // 1
  a:=nil;
  WriteLn(GetRefCount(@a[0])); // Nicht vorhanden
end.


Hierbei würde der Speicher freigegeben werden, und dass obwohl es noch eine Referenz (c) auf den Array gibt. Diese Methode kann zwar Zuteilungen zählen, aber Memoryoperationen umgehen das einfach, und Move ist einfach nur exemplarisch. In diesem Beispiel ist der Fehler leicht zu finden, aber wegen so etwas habe ich mich schonmal in einem eher mittel großen Projekt fast verrückt gemacht.

Ein anderes Beispiel wäre

Code: Alles auswählen

 
type TIntArray: Array of Integer;
var a, b: array of TIntArray;
begin
  SetLength(a, 1);
  SetLength(b, 1);
  a[0] := TIntArray(b);
  b[0] := TIntArray(a);
  a:=nil;
  b:=nil;
end.


Das ist eine Zirkuläre Referenz, auch wenn keine Variable mehr auf die Arrays zeigen, Refenzieren sie sich gegenseitig und so kann die RefCount nicht auf 0 Fallen -> Memory leak.


Wie gesagt an sich finde ich so etwas schon recht angenehm, allerdings hat alles seine Vor und Nachteile, ich z.B. fänd es cool wenn es so etwas wie Ref Count für alle Zeiger gäbe, aber man es mit einem Compiler Switch für jede Unit separat an oder ausschalten könnte

Patito
Beiträge: 203
Registriert: Di 22. Sep 2009, 13:08
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Hat Pascal Probleme mit der Speicherverwaltung?

Beitrag von Patito »

tryunderror hat geschrieben:Frage: Ist das Konzept von Java besser?
Gibt es bessere Speicherverwaltung mit zum Beispiel virtuellem Heap?


Je virtueller der Speicherzugriff wird, umso mehr Bremsklötze hat man im System (-> langsamer ->? schlechter).

Java hält einfach alle Objekte am Leben - mit so einer Messie-Strategie wird es dann schwer
Objekte loszuwerden -> man hat es deutlich schwerer als in Pascal herauszufinden, ob ein eigentlich
veraltetes Objekt nicht doch noch irgendwo verwendet/angezeigt/bestellt/verschickt, ... wird.

Solche Speicherfehler kann man bei den Heap-basierte Objekte von Pascal beim Debuggen sehr gut
auffinden/nachverfolgen (-> Heaptrace). Praktisch hatte ich in Pascal noch nie ein echtes Problem mit Speicherfehlern.

Um auf dasselbe Niveau wie Pascal zu kommen muss man in Java erst Lebenszyklus-Properties einfügen,
und dafür sorgen, dass die überall bei allen Zugriffen beachtet werden (-> sehr viel Code ->? fehleranfällig).

Noch zu C++:
In C++ ist die Speicherverwaltung eine Katastrophe, da dort verschiedene
Arten der Speicherverwaltung (Heap/Stack) gemischt auftreten. Das gibt dann natürlich schnell
ein Chaos. Wer damit eine Zeitlang leben muss, wird zwangsläufig auf die Idee kommen,
dass man ohne Garbage-Collector nicht leben kann - dabei hätte es eigentlich gereicht wenn man
einfach erst mal die Heap- und Stack-basierten Systeme sauber voneinander getrennt hätte.

Insgesamt ist die Speicherverwaltung von Pascal zur Zeit praktisch die beste die es gibt.
Das Problem ist leider nur, dass das ganze Ökosystem von Pascal nicht mehr stabil ist.
Bei FreePascal würde ich fast jede Wette eingehen, dass irgendjemand innerhalb der nächsten
3 Jahre sämtliche Speicherverwaltungs-Probleme von C++ und Java exakt kopiert und fest
in den FPC-Compiler integrieren hat. (leider kein Witz...)

Antworten