[gelöst] Getmem feststellen, wieviel Speicher reserviert wur

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
relocate
Beiträge: 61
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4 + 2.6.4)
CPU-Target: 32Bit

[gelöst] Getmem feststellen, wieviel Speicher reserviert wur

Beitrag von relocate »

Hi,

meine Suche bei Google gibt leider nichts vernünftiges aus, da die Schlagworte wohl zu allgemein sind.
Wenn man per Getmem Speicher für einen Puffer anfordert, ist es möglich später, unabhängig davon, festzustellen,
wieviel Speicher angefordert wurden.
Der Hintergrund ist ja, dass man Freemem nicht übergeben muss, wieviel freigegeben werden muss.
Der Speichermanager merkt sich ja diesen Wert, rückt er irgendwie damit raus (ohne Tricks anzuwenden).
Und wenn, gibt es oder ist das Plattformunabhängig oder zumindest weitestgehend?
Vielleicht hat sich ja jemand schon damit beschäftigt.

Gruß relocate
Zuletzt geändert von relocate am Mi 10. Jan 2018, 12:29, insgesamt 1-mal geändert.
Würde ich die Dinge so wie alle anderen machen, hätte ich so manche Probleme nicht.

Aber das wäre langweilig.

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Getmem feststellen, wieviel Speicher reserviert wurde

Beitrag von marcov »


relocate
Beiträge: 61
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4 + 2.6.4)
CPU-Target: 32Bit

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von relocate »

Bedankt!

boah so einfach.
Der Wert stimmt zwar nicht ganz (die 32 Bit für die Speichervariable wird scheinbar mit zurück gegeben), aber ansonsten stimmt es.
Leider steht das weder bei Getmem https://www.freepascal.org/docs-html/rt ... etmem.html
noch auf der Übersicht (zumindest die ich gefunden habe)... https://www.freepascal.org/docs-html/rt ... tions.html

Gruß relocate
Würde ich die Dinge so wie alle anderen machen, hätte ich so manche Probleme nicht.

Aber das wäre langweilig.

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von marcov »

relocate hat geschrieben:Bedankt!

boah so einfach.
Der Wert stimmt zwar nicht ganz (die 32 Bit für die Speichervariable wird scheinbar mit zurück gegeben), aber ansonsten stimmt es.
Leider steht das weder bei Getmem https://www.freepascal.org/docs-html/rt ... etmem.html
noch auf der Übersicht (zumindest die ich gefunden habe)... https://www.freepascal.org/docs-html/rt ... tions.html

Gruß relocate


An beide hinzugefügt. Korrektion sichtbar in nächster Release.

relocate
Beiträge: 61
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4 + 2.6.4)
CPU-Target: 32Bit

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von relocate »

marcov hat geschrieben:An beide hinzugefügt. Korrektion sichtbar in nächster Release.


Vielleicht mit der Anmerkung, dass der Rückgabewert nicht ganz dem erwartenden entspricht.
Z.B. die Puffergröße war 1024 Byte, der Rückgabewert war 1028.
Die Differenz kommt sehr wahrscheinlich von eben dem Speicherplatz für den Wert zustande.
Das mag ja somit formal richtig sein, jedoch interessiert mich dieser Wert eigentlich nicht,
denn es ist nicht die Puffergröße die nutzbar ist und eben nicht die erwartete Größe.
Würde ich die Dinge so wie alle anderen machen, hätte ich so manche Probleme nicht.

Aber das wäre langweilig.

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

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von Warf »

relocate hat geschrieben:Vielleicht mit der Anmerkung, dass der Rückgabewert nicht ganz dem erwartenden entspricht.
Z.B. die Puffergröße war 1024 Byte, der Rückgabewert war 1028.
Die Differenz kommt sehr wahrscheinlich von eben dem Speicherplatz für den Wert zustande.
Das mag ja somit formal richtig sein, jedoch interessiert mich dieser Wert eigentlich nicht,
denn es ist nicht die Puffergröße die nutzbar ist und eben nicht die erwartete Größe.


Nein der wert ist schon korrekt, nur Getmem macht nicht das was du erwartest. GetMem sagt dem Betriebsystem: Hey ich brauch so viele Bytes an Speicher. Das betriebsystem gibt dann einen Pointer auf einen entsprechend großen Speicherbereich. Dabei kann das Betriebsystem vollkommen frei entscheiden wie viel Speicher es alloziiert, solange es mindestens die erwartete Größe hat. Es könnte auch direkt den gesammten Heap ausfüllen, und dir dann den pointer darauf zurückgeben. Daher sind solche funktionen wie MemSize ganz gefährlich. Es wird sogar noch lustiger, wenn du versuchst Memsize mit einem pointer der in den Stack zeigt aufzurufen bekommst du keine exception, sondern dann bekommst du MaxInt zurück.
Wenn du z.B. eine Funktion wie die hast:

Code: Alles auswählen

procedure FillZero(P: Pointer);
var i: UIntPtr;
begin
  for i:=0 to MemSize(P) -1 do
    PByte(P)[i] := 0;
end;

und die mit einem Stack pointer aufrufst wird die dir schön deine gesammte memory zerstören, bis sie irgendwann eventuell mal eine exception auslöst. Das kann je nach dem in welche richtung der Stack wächst (was auch wieder dem betriebsystem und dem Compiler überlassen ist) sein das du dabei den kompletten stack, also alle Variablen, alle Rücksprungaddressen, etc. überschreibst.

Außerdem kann es sein das das Betriebsystem relevante daten in diesem Overhead speichert.

Langer rede kurzer Sinn, solange du keine detailierten Informationen über dein Betriebsystem hast (also z.B. bei Linux im kernel source mal vorbeischauen), und wie das den heap managed, Finger weg von MemSize

relocate
Beiträge: 61
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4 + 2.6.4)
CPU-Target: 32Bit

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von relocate »

Warf hat geschrieben:Nein der wert ist schon korrekt, nur Getmem macht nicht das was du erwartest.


Ich habe ja nicht gesagt, dass er falsch ist, sondern eben nicht dem erwarteten Wert entspricht, nun gut, dass dann eher Getmem die Ursache ist oder sein soll, ist ja eine andere Sache. Aber auch das könnte man dann eben anmerken!

Warf hat geschrieben:GetMem sagt dem Betriebsystem: Hey ich brauch so viele Bytes an Speicher. Das betriebsystem gibt dann einen Pointer auf einen entsprechend großen Speicherbereich. Dabei kann das Betriebsystem vollkommen frei entscheiden wie viel Speicher es alloziiert, solange es mindestens die erwartete Größe hat.


Stellt sich die Frage, ist das immer so, dann kann man ja eigentlich nie den Speicher sauber verwalten. Wenn das Betriebssystem aber zurückmeldet, hey, ich habe dir so und soviel Speicher reserviert, dann ist ja alles grün. Das ist dann der Wert, den ich von Memsize erwarten würde (wenn man es weiß), es ist natürlich nicht der Wert der angefordert wurde, es ist eigentlich nicht der Wert, mit dem ich mein Programm arbeiten lassen würde, weil ich den ja nicht angefordert habe.

Warf hat geschrieben:Es könnte auch direkt den gesammten Heap ausfüllen, und dir dann den pointer darauf zurückgeben. Daher sind solche funktionen wie MemSize ganz gefährlich. Es wird sogar noch lustiger, wenn du versuchst Memsize mit einem pointer der in den Stack zeigt aufzurufen bekommst du keine exception, sondern dann bekommst du MaxInt zurück.
Wenn du z.B. eine Funktion wie die hast:

Code: Alles auswählen

procedure FillZero(P: Pointer);
var i: UIntPtr;
begin
  for i:=0 to MemSize(P) -1 do
    PByte(P)[i] := 0;
end;

und die mit einem Stack pointer aufrufst wird die dir schön deine gesammte memory zerstören, bis sie irgendwann eventuell mal eine exception auslöst. Das kann je nach dem in welche richtung der Stack wächst (was auch wieder dem betriebsystem und dem Compiler überlassen ist) sein das du dabei den kompletten stack, also alle Variablen, alle Rücksprungaddressen, etc. überschreibst.


Das würde ich aber genau so erwarten (dass Memsize dort nicht richtig arbeiten kann), in dem Fall würde ich Memsize tatsächlich nicht nutzen.

Warf hat geschrieben:Außerdem kann es sein das das Betriebsystem relevante daten in diesem Overhead speichert.


Das würde ich eher vom Speichermanager als vom Betriebssystem erwarten.

Warf hat geschrieben:Langer rede kurzer Sinn, solange du keine detailierten Informationen über dein Betriebsystem hast (also z.B. bei Linux im kernel source mal vorbeischauen), und wie das den heap managed, Finger weg von MemSize


Solche Klippen, die es zu umschiffen gilt, sollten ja eben angemerkt werden, dann von mir aus auch direkt bei Getmem (besser wäre das).
Würde ich die Dinge so wie alle anderen machen, hätte ich so manche Probleme nicht.

Aber das wäre langweilig.

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

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von Warf »

relocate hat geschrieben:Stellt sich die Frage, ist das immer so, dann kann man ja eigentlich nie den Speicher sauber verwalten. Wenn das Betriebssystem aber zurückmeldet, hey, ich habe dir so und soviel Speicher reserviert, dann ist ja alles grün. Das ist dann der Wert, den ich von Memsize erwarten würde (wenn man es weiß), es ist natürlich nicht der Wert der angefordert wurde, es ist eigentlich nicht der Wert, mit dem ich mein Programm arbeiten lassen würde, weil ich den ja nicht angefordert habe.


Genau deshalb ist sowas wie MemSize in anderen Sprachen wie C nicht im Standard. Da kleine Feinheiten wie das praktisch alles kaputt machen können.

relocate hat geschrieben:Das würde ich aber genau so erwarten (dass Memsize dort nicht richtig arbeiten kann), in dem Fall würde ich Memsize tatsächlich nicht nutzen.


Naja je nach Komplexität des Programmes kann man manchmal gar nicht wissen ob ein Pointer aus dem Stack oder dem Heap kommt. Wenn der Pointer durch verschiedene Prozeduren gejagt wird bist die Herkunft unbekannt ist hat man halt schon verloren. Man kann zwar mit ein paar tricks überprüfen ob der Pointer auf den stack zeigt, aber sobald man mehrere Threads hat, die verschiedene Stacks hat, hat man keine Chance.
Und bei dem text:
Passing an invalid pointer may lead to run-time errors (access violations).

in der Dokumentation hätte ich einen Stack test irgendwie erwartet (oder zumindest einen Satz wie: does not work on stack pointers)

relocate hat geschrieben:Das würde ich eher vom Speichermanager als vom Betriebssystem erwarten.

Stimmt, habe total vergessen das Pascal ja diverse MemoryManager unterstützt (da merkt man das ich viel zu viel mit C arbeite). Da geht alles über den MM. Du könntest mal die unit cmem versuchen, damit kannst du wenigstens davon ausgehen wenn die libc die selbe ist, das dann auch der Overhead der selbe ist

relocate hat geschrieben:Solche Klippen, die es zu umschiffen gilt, sollten ja eben angemerkt werden, dann von mir aus auch direkt bei Getmem (besser wäre das).

Ja die Dokumentation könnte besser sein (nicht das man da nicht selbst Hand anlegen könnte, meckern ist aber viel einfacher :mrgreen: )

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von marcov »

Memory managers verwalten Speicher typisch mit eine Granularität großer als 1, zb 8 oder 16 byte. Das ist um Speicher zu sparen, mit geringere Werten werden der Administration großer dann die Ersparnisse.

relocate
Beiträge: 61
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4 + 2.6.4)
CPU-Target: 32Bit

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von relocate »

Warf hat geschrieben:Genau deshalb ist sowas wie MemSize in anderen Sprachen wie C nicht im Standard. Da kleine Feinheiten wie das praktisch alles kaputt machen können.


Problematisch ist es natürlich immer, wenn man nicht sicher sein kann, dass sich eine Funktion so verhält wie man es erwartet. Umso besser sollte die Definition sein. Ist ja auch bei der Unicode Kodierung so. Man muss halt hoffen, dass es passt. Ich arbeite in meinem Problemfall mit dem Wert, den ich vorgegeben habe, aber habe mir eben Gedanken gemacht, was ist, wenn ich es woanders benötige, dann müsste ich den Wert ja immer weiterverarbeiten, aber Freemem kann es ja ohne. Und wenn ich mit Freemem den Speicher freigebe, sollte dem Speichermanager schon klar sein, was er zu tun hat (genau den Wert freizugeben) und deshalb sollte es eigentlich schon möglich sein, den erwarteten Wert zurückzugeben. Denn der Speichermanager sollte es wissen. Gut er weiß natürlich, wieviel reserviert wurde und nicht wieviel ich wollte, aber theoretisch sollte auch der Wert verwaltet werden können.

Warf hat geschrieben:Naja je nach Komplexität des Programmes kann man manchmal gar nicht wissen ob ein Pointer aus dem Stack oder dem Heap kommt. Wenn der Pointer durch verschiedene Prozeduren gejagt wird bist die Herkunft unbekannt ist hat man halt schon verloren. Man kann zwar mit ein paar tricks überprüfen ob der Pointer auf den stack zeigt, aber sobald man mehrere Threads hat, die verschiedene Stacks hat, hat man keine Chance.
Und bei dem text:
Passing an invalid pointer may lead to run-time errors (access violations).

in der Dokumentation hätte ich einen Stack test irgendwie erwartet (oder zumindest einen Satz wie: does not work on stack pointers)


Genau deshalb würde ich es nicht erwarten. Gerade bei einem untypisierten Pointer.

Warf hat geschrieben:Stimmt, habe total vergessen das Pascal ja diverse MemoryManager unterstützt (da merkt man das ich viel zu viel mit C arbeite). Da geht alles über den MM. Du könntest mal die unit cmem versuchen, damit kannst du wenigstens davon ausgehen wenn die libc die selbe ist, das dann auch der Overhead der selbe ist


Das wäre natürlich eine Möglichkeit, könnte sich das nicht aber auch mal ändern. Oder man erweitert das gleich selbst, sprich man setzt selbst ein Marker an das Ende um dort zu speichern was man wollte. Muss natürlich konsequent sein.

Warf hat geschrieben:Ja die Dokumentation könnte besser sein (nicht das man da nicht selbst Hand anlegen könnte, meckern ist aber viel einfacher :mrgreen: )


Würde ich ja tun, wenn ich könnte (können dürfen und können können, man muss es ja erstmal wissen)?
Würde ich die Dinge so wie alle anderen machen, hätte ich so manche Probleme nicht.

Aber das wäre langweilig.

relocate
Beiträge: 61
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4 + 2.6.4)
CPU-Target: 32Bit

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von relocate »

marcov hat geschrieben:Memory managers verwalten Speicher typisch mit eine Granularität großer als 1, zb 8 oder 16 byte. Das ist um Speicher zu sparen, mit geringere Werten werden der Administration großer dann die Ersparnisse.


Das ist ja klar. Nur ist eben die Frage, was interessiert den Programmierer, was der Memorymanager intern macht. Wenn man Memsize nicht präszise nutzen kann, sondern nur um eben festzustellen ist der Speicher groß genug, also größer gleich dem was ich speichern will oder ist er genau so groß wie ich ihn benötige sind das zwei unterschiedliche Anforderungen, wobei eine abgedeckt wird, die andere nicht, aber wie gesagt, muss man ja erst einmal wissen.
Würde ich die Dinge so wie alle anderen machen, hätte ich so manche Probleme nicht.

Aber das wäre langweilig.

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: [gelöst] Getmem feststellen, wieviel Speicher reserviert

Beitrag von marcov »

relocate hat geschrieben:
marcov hat geschrieben:Memory managers verwalten Speicher typisch mit eine Granularität großer als 1, zb 8 oder 16 byte. Das ist um Speicher zu sparen, mit geringere Werten werden der Administration großer dann die Ersparnisse.


Das ist ja klar. Nur ist eben die Frage, was interessiert den Programmierer, was der Memorymanager intern macht. Wenn man Memsize nicht präszise nutzen kann, sondern nur um eben festzustellen ist der Speicher groß genug, also größer gleich dem was ich speichern will oder ist er genau so groß wie ich ihn benötige sind das zwei unterschiedliche Anforderungen, wobei eine abgedeckt wird, die andere nicht, aber wie gesagt, muss man ja erst einmal wissen.


Ich denke memsize ist meistens für die RTL, zb wenn ein String laenger gemacht wird. Und dann ist tatsächliche Menge Bytes wichtig, nicht die originelle Zahl.

Antworten