Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   C++ Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar. (https://www.delphipraxis.net/195586-fehler-fuer-diesen-befehl-ist-nicht-genuegend-speicher-verfuegbar.html)

Michaell 12. Mär 2018 10:28

Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Hallo,

es gibt hier im Forum viele Anfragen zur Fehlermeldung:
Für diesen Befehl ist nicht genügend Speicher verfügbar.
bzw.:
Not enough storage is available to process this command.
Diese sind alle älter als 5 Jahre und ich konnte auch nichts "passendes" dazu finden:

Kürzlich mußte ich meine benötigte Bitmapgröße auf 8832 * 8832 Pixel erweitern. Beim Programmstart kommt nun bei manchen meiner Rechner (Windows 7, 32 Bit und Windows 10, 32 Bit) die obige Fehlermeldung. Der Trigger für die Fehlermeldung ist hier:
Code:
void __fastcall CBitmapImage::Init()
{
   // generate and init bitmap object
   Bitmap = new Graphics::TBitmap();
   Bitmap->Height = Height; // 8832 pixel
   Bitmap->Width = Width; // 8832 pixel
}
Bei der "Width" Zuweisung passiert es. Wenn ich das richtig berechnete habe, so würde ein 27 MiB Speicherblock benötigt. Klingt für mich nicht nach viel ...
noch ein paar Details:
  1. Mein Prog. belegt nach dem Start 265 MiB RAM.
  2. Alle PCs haben 4 GiB RAM und der ist nicht mal zur Hälfte gefüllt (von den ca. 3 GiB die verfügbar sind).
  3. Ich Verwende den C++ Builder 10.2 mit dem klassischen Compiler.
Wie kann ich dieses Problem beheben? Vielen Dank!

Grüße!

Michael

Der schöne Günther 12. Mär 2018 10:39

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Hinweis: Meiner Rechnung nach liegst du eine Zehnerpotenz zu niedrig was den Platzverbrauch angeht.

bra 12. Mär 2018 10:48

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
8832 * 8832 * 4 (32 Bit) = 312.016.896. Je nachdem wie das im Speicher liegt noch viel mehr. Irgendwas rechnest du da falsch.

KodeZwerg 12. Mär 2018 10:50

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Ich hab 2,32GB als benötigte Daten-Menge, ich glaub bei 2,5GB ist mit 32bit Schluß?

Michaell 12. Mär 2018 10:56

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1395839)
Ich hab 2,32GB als benötigte Daten-Menge, ich glaub bei 2,5GB ist mit 32bit Schluß?

Danke, das würde das Ganze erklären. Das meine Rechnung:
8832 * 8832 = 78.004.224 Pixel
Fuer Farbdarstellung benoetigt man 3 bit per Pixel und somit sind es 234.012.672 bit = 29.251.584 byte = 27 MiB
nicht stimmen konnte dachte ich mir schon, es ergab keinen Sinn in Bezug auf den Fehler. Ich weiß darüber einfach zu wenig.

Der schöne Günther 12. Mär 2018 11:00

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Michaell (Beitrag 1395840)
Fuer Farbdarstellung benoetigt man 3 bit per Pixel

Je nachdem was für elaborate Formate du einsetzt kann man das sicherlich schaffen, aber bei einer stinknormalen TBitmap hätte ich jetzt eher auf 4 Byte pro Pixel getippt.

hstreicher 12. Mär 2018 11:16

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Der Speicher muss aber auch zusammenhängend frei verfügbar sein wenn er angefordert wird
insofern ist die Windows Anzeige von Freiem Speicher nicht aussagekräftig

mfg Hannes

KodeZwerg 12. Mär 2018 11:17

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Also meine Angabe da oben bezieht sich auf ein Standard 32bit (4 byte pro Pixel) Format, keine Eigenkreation.

Zacherl 12. Mär 2018 11:34

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von hstreicher (Beitrag 1395843)
Der Speicher muss aber auch zusammenhängend frei verfügbar sein wenn er angefordert wird

Das ist der Knackpunkt!

Eventuell könntest du dein Bitmap in 4 (oder noch mehr) Quadranten einteilen und bei der Anzeige wieder zusammensetzen? Dann würde es reichen mehrere nicht-zusammenhängende kleinere Speicherblöcke zu reservieren. Und 24- bzw. sogar 32-Bit pro Pixel sind tatsächlich Standard unter Windows, also kommst du auf knapp 300MiB bei deiner Bildgröße.

Michaell 12. Mär 2018 11:38

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1395844)
Also meine Angabe da oben bezieht sich auf ein Standard 32bit (4 byte pro Pixel) Format, keine Eigenkreation.

OK, dann ergibt sich 8832 * 8832 * 4 byte = 312.016.896. Das Ganze ist dann 32 Bit aligned also 312.016.896 * 4 = 1.248.067.584 Bytes = 1190.25 MiB. Da fehlen mir jetzt aber 50% Deiner 1sten Angabe von 2,32 GB ...

bra 12. Mär 2018 11:51

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Michaell (Beitrag 1395848)
OK, dann ergibt sich 8832 * 8832 * 4 byte = 312.016.896. Das Ganze ist dann 32 Bit aligned also 312.016.896 * 4 = 1.248.067.584 Bytes = 1190.25 MiB. Da fehlen mir jetzt aber 50% Deiner 1sten Angabe von 2,32 GB ...

Keine Ahnung von was du da redest, aber ein Bitmap in der Größe mit 32 Bit sind ~300 MB.

himitsu 12. Mär 2018 11:59

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Alle PCs haben 4 GiB RAM
Erstmal hast du ein 32 Bit-Programm und diese haben standardmäßig nur einen virtuellen Speicher von 2 GB.
Kann per Compiler-Befehl auf 3 GB (32 Bit Windows) oder fast 4 GB (64 Bit Windows) erhöht werden. Vielleicht reicht das bei dir aus.

Windows hat auch noch eine Auslagerungsdatei, womit die 4 GB physicher RAM im globaler Speicher mehr sind.
Selbst bei 1 GB RAM kann ein Programm diese 2 GB nutzen (wenn genügend freier Speicher inkl. Pagefile vorhanden sind)

Und wie bereits erwähnt liegt beim BITMAP der Speicher als ein zusammenhöngender Block vor und da wird es in 32 Bit-Programmen ab durchschnittlich 250-300 MB schnell eng,
zwischen all den geladenen DLLs, der EXE und dem restlichen genutzten Arbeitsspeicherstückchen, sind nur selten größere Bereiche verfügbar.

Im FastMM oder Hier im Forum suchenHxD kannst du dir das leicht ansehn.
https://stackoverflow.com/questions/...elphi-applicat
https://mh-nexus.de/de/hxd/

Die Executables (DLL/EXE) liegen nicht immer auf der selben Adressen.
https://en.wikipedia.org/wiki/Relocation_(computing)
Und auch der restliche dynamische Speicher wird mehr "zufällig" verteilt reserviert.

Michaell 12. Mär 2018 13:10

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Danke himitsu, von Deinen Aussagen ist die hier nach meiner derzeitigen Meinung der Knackpunkt:
Zitat:

Zitat von himitsu (Beitrag 1395853)
...
Und wie bereits erwähnt liegt beim BITMAP der Speicher als ein zusammenhöngender Block vor und da wird es in 32 Bit-Programmen ab durchschnittlich 250-300 MB schnell eng, zwischen all den geladenen DLLs, der EXE und dem restlichen genutzten Arbeitsspeicherstückchen, sind nur selten größere Bereiche verfügbar.

Weil das Problem nicht immer auftritt und öfters ein Neustart des betroffenen PCs reicht um keinen Fehler zu bekommen.
Das Problem ist also:
Ich habe im 2 GiB Virtuellen-Adressraum meines Programms öfters mal keinen zusammenhängenden Bereich von 297.5625 MiB (8832 * 8832 * 4 Bytes) übrig um meine Speicheranforderung zu bedienen.
Lösungsmöglichkeit:
Das Problem kann evtl. dadurch umgangen werden, das man dem Compiler mitteilt, das er 3 GiB Virtuellen-Adressraum nutzen soll.

OK, ich werde sehen wie ich das hinbekomme und Melde mich dann.

Der schöne Günther 12. Mär 2018 13:25

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Damit verschleppst du das Problem höchstens ein bisschen.

Dein Problem ist dass du Speicherfragmentierung hast. Ich kenne TBitmap zu wenig, aber vielleicht kann man den Bereich früh einmal anfordern und dann nicht mehr freigeben? Notfalls erstellst du einmal dein entsprechendes TBitmap und arbeitest immer mit dieser einen Instanz weiter.

Michaell 12. Mär 2018 13:37

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1395857)
Damit verschleppst du das Problem höchstens ein bisschen.

Dein Problem ist dass du Speicherfragmentierung hast. Ich kenne TBitmap zu wenig, aber vielleicht kann man den Bereich früh einmal anfordern und dann nicht mehr freigeben? Notfalls erstellst du einmal dein entsprechendes TBitmap und arbeitest immer mit dieser einen Instanz weiter.

Genau das mache ich zur Zeit, deshalb kommt doch auch beim Programstart die Meldung. Der Tipp hier ist aber "... den Bereich früh einmal anfordern ..." -> ich muß mir die Reihenfolge meiner vielen "new" ansehen und gegebenenfalls bzw. wenn möglich umsortieren.

P.S. Eine Compiler Option für "3 GiB virtual address space" konnte ich bisher nicht finden.

Zacherl 12. Mär 2018 13:42

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Eine zuverlässige Lösungsmöglichkeit, die nicht auf irgendwelchen esoterischen Windows Speicherverwaltungs-Optionen oder Compiler-Switches basiert, habe ich weiter oben bereits genannt.

Uwe Raabe 12. Mär 2018 13:43

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Michaell (Beitrag 1395858)
P.S. Eine Compiler Option für "3 GiB virtual address space" konnte ich bisher nicht finden.

Vergrößern des Speicheradressraums

himitsu 12. Mär 2018 13:49

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Du hast 4 GB physisch und das sind meistens 6-8 GB global.
Ja, wenn da "insgesamt" weniger zur Verfügung steht, als dein Programm anfragt, dann knallt es auch.

> im physischen RAM und der Auslagerungsdatei muß der Block nicht zusammenhängen (er kann auch fragmentiert dem virtuellen Block zugewiesen sein ... wird zur Laufzeit dynamisch zugewiesen/umkopiert)
> in deinem privaten virtuellen Prozessspeicher ist ein Bitmap oder ein String oder ein Array immer am Stück und muß somit einem zusammenhängenden Bereich Platz finden.

Code:
**************** 16 MB RAM
   * ** ***   *  7 MB schon belegt

********         9 MB sind zwar noch frei, aber ein 8 MB-Bitmap passt dennoch nicht in eine der oberen Lücken
Windows versucht auf Home-Systemen die Binaries (DLL/EXE) zwischen den Prozessen zu sharen und wiederverwendet vorberechnete DLLs.

Wird eine DLL/EXE verschoben, dann muß deren Speicher angepasst werden, also überall die Adressen anpassen.
Da ist es einfacher das nur einmal zu machen und dann allen Programmen die selbe angepasste DLL zu geben > nur einmal "real" Speicher, auf den alle Programme nur virtuell verweisen. (wird aber nicht dauerhaft gespeichert und ist beim Neustart erstmal weg)
Spart beim Programmstart zeit, wenn die DLL schon fertig berechnet wiederverwendet wird. (OK, damals waren die Computer noch etwas langsamer und hatten weniger RAM)
http://www.drdobbs.com/rebasing-win32-dlls/184416272
https://en.wikipedia.org/wiki/Relocation_(computing)

Auf Server-Systemen geht man davon ab (kann man auch für User-Systeme aktivieren), damit bei jedem Programm die selbe DLL nicht an der selben virtuellen Stelle liegt.
Macht das blinde Hacken mit statischen Adressen nahezu unmöglich. (schwerer für Viren, Trojaner usw.)
https://de.wikipedia.org/wiki/Addres..._Randomization


PS: Im Taskmanager gibt es mehrere Werte für den Arbeitsspeicher.
"Zugesicherte Größe" ist das, was dein Programm wirklich verbraucht.
und "Arbeitsspeicher (privater Arbeitssatz) dürfte das sein, was davon grade im physischen RAM liegt. (der Rest ist ausgelagert)

* aktiver Speicher > das was grade im RAM liegt
* reservierter Speicher > das was in deinem virtuellen Speicher belegt ist (inkl. oder exkl. gemapptem Speichers > z.B. EXE/DLL und MMF aka Memory-Mapped-Files)
* und es gibt Speicher, den du reserviert hast, der aber grade nicht in deinem virtuellen Speicher gemappt ist (wird von normalen Programmen selten genutzt)
* uvm.

Michaell 12. Mär 2018 14:24

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1395860)
Zitat:

Zitat von Michaell (Beitrag 1395858)
P.S. Eine Compiler Option für "3 GiB virtual address space" konnte ich bisher nicht finden.

Vergrößern des Speicheradressraums

Vielen Dank für den Link (der bei mir nicht funktioniert aber aus dem Link Text konnte ich im Embarcadero-Wiki unter der Überschrift "Vergrößern des Speicheradressraums" alles finden.) Der Wiki Text sagt u.a.:
  1. "... führen Sie den bcdedit /set {ID} increaseuserva 3072-Befehl aus." D.h. doch ich müßte das dann auf jedem PC machen, wo das Prog. laufen soll? Falls ja: Die Option ist damit unbrauchbar, ich habe nicht auf alle PCs zugriff.
  2. Weiterhin "Stellen Sie sicher, dass alle Bibliotheken und Komponenten von Fremdherstellern den größeren Adressraum unterstützen." und damit ist das der 2te Grund das nicht zu versuchen.
Ich kann den Kommentar "... die nicht auf irgendwelchen esoterischen Windows Speicherverwaltungs-Optionen ..." von Zacherl nun gut nachvollziehen.

himitsu 12. Mär 2018 14:39

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Bei halbwegs aktuellen 64 Bit-Windowsen ist das standardmäßig schon seit Jahren aktiviert.

Zitat:

Delphi-Quellcode:
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}

Nur das muß noch in dein Programm einkompiliert werden, damit Windows weiß, dass dein Programm mehr als 2 GB vertragen kann und es somit auch anfordert.

Es gab "früher" viele Programmierer, die hatten
Delphi-Quellcode:
Integer(Pointer) <= 0
als "ungültig" angesehn und dann teilweise in diesem Bereich sogar Zusatzinfos im Pointer gespeichert.
Sowas knallt, wenn Windows dem Programm plötzlich mehr als 2 GB Speicher gibt ... darum muß das im Programm erst aktiviert werden.

Michaell 12. Mär 2018 14:46

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von himitsu (Beitrag 1395863)
Bei halbwegs aktuellen 64 Bit-Windowsen ist das standardmäßig schon seit Jahren aktiviert.

Wie im 1sten Beitrag geschrieben: Die PCs wo meine SW läuft verwenden Win 7 oder Win 10 jeweils in der 32 Bit Version. Nur mein Entwicklungsrechner ist 64 Bit und dort hatte ich das Problem noch nie.

himitsu 12. Mär 2018 14:53

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
3-GB und 4-GB ist quasi das Gleiche.

3-GB deshalb, weil ein 32 Bit-Windows den letzten 1 GB für Treiber und Cache nutzt und daher nicht den User-Mode-Programmen zur Verfügung stehen.
In 64 Bit-Windows sind für 32 Bit Programme daher bis zu den vollen 4 GB nutzbar.
(die ersten 64 KB sind aber nie nutzbar und sind immer nur Treibern vorbehalten, als Puffer für die Übergabe in den Programmspeicher)

Je nach Windows-Version und verfügbaren RAM sind dann halt 3, 3.5, "ewta" 3.75 oder eben 4 GB im Programm, bzw. "physische" für alle Programme nutzbar.



Tja, im 32 Bit-Windows ... k.A. wie es da in aktullen Windowsen (nach Windows 9x) aussieht, also ob schon aktiv oder nicht.
Du kannst dir eine Testanwendung schreiben,
die 4GB-Option aktivieren (
Delphi-Quellcode:
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
),
MSDN-Library durchsuchenGlobalMemoryStatusEx abfragen, ullTotalVirtual anzeigen (MSDN-Library durchsuchenMEMORYSTATUSEX)
und dann ausprobieren was überall geht.


[info]
Effektiv kann ein Programm in jedem 32 Bit-Windows auch über 4 GB Arbeitsspeicher verwalten. (z.B. über Pageing, MemoryMapping usw.)

Ich habe hier ein kleines Testprogramm (32 Bit-Konsolenanwendung), das reserviert sich physischen Speicher und macht dir locker 100 GB RAM voll, ohne dass der Speicher ausgelagert werden kann (Pagefile).
Aber das hilft dir nicht viel, da du den Speicher nicht selber verwaltest.

Michaell 12. Mär 2018 15:46

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Michaell (Beitrag 1395858)
Genau das mache ich zur Zeit, deshalb kommt doch auch beim Programstart die Meldung. Der Tipp hier ist aber "... den Bereich früh einmal anfordern ..." -> ich muß mir die Reihenfolge meiner vielen "new" ansehen und gegebenenfalls bzw. wenn möglich umsortieren.
...

Das war tatsächlich möglich: Via 'Project -> Options -> Forms' kann man alle Formulare sortieren. Ich habe also mein frmBitmap an die 2te Stelle nach meinem Hauptformular verschoben. Das kann man dann auch in der <ProjectName>.cpp Datei sehen:
Code:
...
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{    try
     {
                 Application->Initialize();
                 Application->HelpFile = "";
       Application->CreateForm(__classid(Tfrm_MainWin), &frm_MainWin);
       Application->CreateForm(__classid(TfrmBitmap), &frmBitmap);
       Application->CreateForm(...
     }
     catch ...
}
Dort habe ich dann einen Breakpoint gesetzt, step over durchgeführt und Sch... der Fehler ist noch immer da. :(
Widerspricht das nicht der Annahme, das ich im 2 GiB Adressraum meines Progs. zwar genug freie Speicherbereiche habe aber halt keinen der die benötigten ca. 300 MiB hat?

EWeiss 12. Mär 2018 17:38

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Wo ist denn dein Problem mache es doch so wie Zacherl gesagt hat teile das Bitmap in 4 oder mehr Teile auf und gut ist.
Irgendwann wirst du immer an eine grenze stoßen und dann ?
Fängst wieder von vorne an.

gruss

himitsu 12. Mär 2018 18:36

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Delphi-Quellcode:
Application->CreateForm(...

k.A. wie viel das ist,
aber, wenn man sich schon bei Programmstart mit allem Möglichen den Speicher zumüllt, dann kann es schonmal bissl eng werden.

Man kann alternativ die Forms auch erst dann "dynamisch" erzeugen, wenn man sie wirklich braucht.


Aber so oder so, ab spätestens 250-300 MB gibt es immer mal Probleme, in 32 Bit-Anwendungen. (persönliche Erfahrungswerte)
Die einzig sichere Lösung ist also ein Auftrennen oder Verkleinern dieses großen Blocks. (oder in einen separaten Prozess auslagen oder 64 Bit)

Der schöne Günther 12. Mär 2018 18:54

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Ich verstehe noch nicht was
Delphi-Quellcode:
Application->CreateForm
damit zu tun hat. Kann man die Bitmap nicht vor den ganzen Formularen erstellen? Wenn man dann noch nicht einmal 300 MB am Stück hat würde ich mich allerdings auch wundern :!:

himitsu 12. Mär 2018 19:39

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Für die 300 MB ist so schon kaum freier Speicher.
Wenn du vorher nun noch mehr Speicher im RAM belegst, dann erhöht sich die Chance, dass kein zusammenhängender 300 MB-Block mehr verfügbar ist.

KodeZwerg 12. Mär 2018 20:06

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Du könntest dir eine Prozedur schreiben die den komplett installierten (nicht nur den freien) Speicher belegt so das Windows gezwungen wird Auszulagern, nun gib den Speicher wieder frei, je nach Windows Einstellung steht Dir nun sehr viel mehr am Stück zur Verfügung oder Dll's von anderen Anwendungen laden sich selbst wieder in den schnellen Speicher, das mehr frei ist > ist ein positiver Nebeneffekt, das es Zeit kostet (auch Windows Nachladezeit, da alle Caches danach überfüllt bzw geleert sind) ist als negativer Aspekt anzusehen (Icons Fenter Text Farben alles wird neu erschaffen).
(Ziel der Übung: Memory Defrag)

Der schöne Günther 12. Mär 2018 21:20

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das ist nicht richtig.

Was Windows macht ist völlig unerheblich, Windows hat genug Puste. Eine Anwendung (z.B. Delphi) arbeitet sowieso nicht mit "echtem" Hauptspeicher sondern mit virtuellem Speicher. Das Betriebssystem (z.B. Windows) kümmert sich in Kombination mit spezieller Hardware-Beschleunigung aus der CPU um die Übersetzung von virtuellen Adressen deines Prozesses in die entsprechenden "echten" Speicheradressen.

Der virtuelle Speicher ist hierbei weiterhin in Seiten unterteilt. Das Ein- und Auslagern betrifft Seiten. Es ist egal welche Seiten Windows hier ein- und auslagert, das Problem betrifft seinen privaten, virtuellen 2GB-Adressraum für seinen Prozess. Davon dass diese Seiten auch wild über den Arbeitsspeicher verteilt sein können (siehe Bild) wollen wir gar nicht erst anfangen.

Viele kleine Stücke zu belegen und anschließend freizugeben verändert nicht die "Reihenfolge" in diesem Adressraum. Es wird ihm danach nicht mehr zusammenhängender Speicher zur Verfügung stehen.

Viel Zeit zum Lesen?
  1. https://de.wikipedia.org/wiki/Paging
  2. Silberschatz et. al: Operating System Concepts

Luckie 12. Mär 2018 21:51

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Ich denke, da läuft grundsätzlich was falsch bei ihm. Man nehme doch nur mal Photoshop oder Audio-Bearbeitungsprogramme, die auch schon unter 32 Bit mit großem Dateien umgehen konnten. Also ich bin ja meist der Überzeugung, wenn man an die Grenzen von Windows stößt, macht man was falsch.

himitsu 13. Mär 2018 08:45

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1395888)
je nach Windows Einstellung steht Dir nun sehr viel mehr am Stück zur Verfügung

Nein, eben nicht. Auf den virtuellen Speicher jedes Prozesses hat es absolut keinen Einfluss.
Im Gegensatz, für das Gesamtsystem machen solche "RAM-Optimierer" das Schlimmste, was nur geht. Es wird Alles ausgelagert und anschließend muß überall wieder der aktuell genutzte Speicher wieder zurück, was somit alle Programme ausbremst.

Für sowas wäre es schöner, wenn Windows eine bessere Unterstützung zur Steuerung der FileCache bietet,
denn das Einzige was dieser Optimierer erreicht ist das leeren dieser Cache (der Prozessspeicher wird ja sowieso wieder zurückgeladen, sobald darauf zugegriffen wird)
Wenn neuer Speicher in dem vollen physischen RAM nötig wird, dann lagert Windows schon von selber Speicher aus. (leider wird entgegen der möglichen Einstellung "Prozessspeicher zu bevorzugen" von Windows der FileCache bevorzugt, was bei großen Lese-/Schreib-/Kopieraktionen die Programme aus dem RAM verdrängt und Windows sie erst wieder laden muß, wenn sie auf ihren Speicher zugreifen wollen)


Aber das Ändert rein garnichts an dem Problem mit seinem fragmentierten virtuellen Speicher.
Ein PageError, weil ein Speicherblock (Page) grade nicht im RAM war, dass bekommt sein Programm garnicht mit. Es wird nur ein bisschen langsamer, aber an der Größe und Belegung seines virtuellen Speichers ändert sich nichts ... da wo die Page eingebungen ist, da bleibt sie auch. Es darf sich auch garnichts verschieben, da sonst alle Pointer ein Problem hätten, die darauf zeigen. Darum auch die Trennung zwischen Virtuellem und Physischen Speicher, damit Windows dort den realen Speicher verschieben kann wie es will, ohne dass das Programm es zu interessieren hat.

bra 13. Mär 2018 11:42

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1395888)
Du könntest dir eine Prozedur schreiben die den komplett installierten (nicht nur den freien) Speicher belegt so das Windows gezwungen wird Auszulagern, nun gib den Speicher wieder frei, je nach Windows Einstellung steht Dir nun sehr viel mehr am Stück zur Verfügung oder Dll's von anderen Anwendungen laden sich selbst wieder in den schnellen Speicher, das mehr frei ist > ist ein positiver Nebeneffekt, das es Zeit kostet (auch Windows Nachladezeit, da alle Caches danach überfüllt bzw geleert sind) ist als negativer Aspekt anzusehen (Icons Fenter Text Farben alles wird neu erschaffen).
(Ziel der Übung: Memory Defrag)

Sorry, aber das ist einer der dümmsten Vorschläge die ich seit langem gelesen habe. Wenn ein Programm sowas machen würde, wäre das innerhalb von Sekunden wieder deinstalliert und der Entwickler auf ewig auf meiner Blacklist.

Michaell 13. Mär 2018 13:44

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Danke an alle für Eure rege Teilnahme an meinem Problem!

Was warum auch immer mit dem TBitmap bei mir zur genannten Fehlermeldung führt kann ich nicht ergründen, denn selbst wenn die Fehlermeldung nicht kommt habe ich laut Task Manager nur 265 MiB Speicher belegt.
Die Anforderungen an mein "großes Bitmap" sind hingegen bekannt und zu meinem Glück brauche ich nur das: 'Pixel ist gezeichnet oder nicht gezeichnet'. Deshalb habe ich jetzt mit
Code:
Bitmap->PixelFormat = pf1bit;
einfach ein schwarz / weiß Bitmap erstellen lassen -> Fehler ist weg und damit auch mein Problem. (Der Befehl muß vor der Zuweisung von Height and Width eingefügt werden.)

himitsu 13. Mär 2018 13:55

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Michaell (Beitrag 1395942)
Was warum auch immer mit dem TBitmap bei mir zur genannten Fehlermeldung führt kann ich nicht ergründen, denn selbst wenn die Fehlermeldung nicht kommt habe ich laut Task Manager nur 265 MiB Speicher belegt.

Der Grund (Speicher-Fragmentierung) wurde doch schon mehrmals genannt?

Wenn du in 2 GB Prozessspeicher alle 200 MB je 1 Byte speicherst, dann hast du 10 Byte belegt.
OK, eigentlich 41 KB, da Windows den Speicher in 4 KB-Blöcken vewaltet.

Obwohl also nur 41 KB belegt sind, hast du dennoch keine Chance dort einen freigen zusammenhängenden Block mit 300 MB zu finden.



Belegt und Verwendet ist auch ein Unterschied. Du kannst 400 MB Speicher reservieren, aber wenn dort nicht reingeschrieben wurde (alles mit Nullen gefüllt), dann ist dieser Speicher nicht belegt.

Wie ebenfalls schon genannt wurde, hat der Taskmanager unterschiedliche Anzeigen für "belegten" Speicher. (es gibt noch viel mehr Spalten, die man sich da anzeigen lassen kann)

Michaell 13. Mär 2018 14:16

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von himitsu (Beitrag 1395945)
Der Grund (Speicher-Fragmentierung) wurde doch schon mehrmals genannt?

Ja, nur das ich daran seit meinem Umsortieren der Forms nicht mehr Glaube! (Ich schreibe nichts von Wissen.)

Zum Task Manager (Windows 7): Der Wert von 265 MiB stammt vom Reiter 'Processes', Spalte 'Memory (Private Working Set)'. Eine andere Stelle kenne ich nicht, auch nicht Optionen um das zu ändern.

Michaell 13. Mär 2018 14:20

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Michaell (Beitrag 1395947)
... Eine andere Stelle kenne ich nicht, auch nicht Optionen um das zu ändern.

OK, hab die Optionen gefunden. Mal sehn ob sich damit etwas mehr Information gewinnen läßt.

himitsu 13. Mär 2018 15:08

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Alter Taskmanager (Win XP/7) im Menü Ansicht
und beim Neuen Windows 8/10 im Kontextmenü der Gridspalten.

Zitat:

Ja, nur das ich daran seit meinem Umsortieren der Forms nicht mehr Glaube!
Und warum nicht?

Werden die anderen Forms erst danach erstellt, dann verteilen sie ihren Speicher auch nicht vorher und sorgen so eventuell für ein Belegen des großen Speicherblocks.
Nachher passen aber deren viele kleinen Speicherblöcke in die verbliebenen Lücken.

ABER, dass bedeutet nicht, dass vorher nicht schon durch was Anderes der Speicher schon zu sehr fragentiert sein kann.
z.B. neue DLLs in neueren Windowsen und dann bringen auch Zusatzprogramme, wie z.B. Drucker-, Monitor-Treiber, TeamViewer, Skype usw. ihre DLLs in alle fremden Prozesse, also auch in deine Anwendung und schwupps, schon kann es plötzlich wieder nicht mehr funktionieren, egal ob deine Forms danach sind, weil schon viele Anderes unvorhersehbar vorher abläuft.

Michaell 13. Mär 2018 16:50

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Zitat:

Zitat von Michaell (Beitrag 1395948)
OK, hab die Optionen gefunden. Mal sehn ob sich damit etwas mehr Information gewinnen läßt.

Ich habe nun drei neue "Memory" Spalten im Task Manager, die neue max. angezeigte Speichergröße ist ca. 300 MiB und aus Spalte Peak Working Set (Memory) entnommen. Nach wie vor sieht man keine großartige Speicherbelegung. Ist mir aber auch egal, der Fehler tritt nicht mehr auf und ich will keine weitere Zeit dazu spendieren.

bra 14. Mär 2018 09:41

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Es geht ja nicht darum, wieviel Speicher insgesamt zur Verfügung steht, sondern wieviel Speicher an einem Stück zur Verfügung steht. Wenn du zwar 2 Gb frei hast, aber alle 20 MB mal ein paar Byte stehen, bekommst du nie 300 MB am Stück unter. Da kannst du dich drehen und wenden soviel du willst. Dass es jetzt vielleicht funktioniert, heisst noch lange nicht, dass es dauerhaft funktioniert. Einmal Neustarten, 3-4 Programme starten und schon sieht die Speicherfragmentierung wieder ganz anders aus.

KodeZwerg 14. Mär 2018 13:19

AW: Fehler: Für diesen Befehl ist nicht genügend Speicher verfügbar.
 
Es wurde ja bereits verkündet das meine Idee mit Speicher füllen falsch sei, ich habe es so getestet:

Delphi-Code:
Code:
procedure MyTrimWorkingSet;
var hProcess: THandle;
begin
 hProcess := OpenProcess(PROCESS_SET_QUOTA, false, GetCurrentProcessId);
 try
  SetProcessWorkingSetSize(hProcess, $FFFFFFFF, $FFFFFFFF);
 finally
  CloseHandle(hProcess);
 end;
end;
Könnte mir bitte jemand sagen was daran falsch sei damit ich es endlich Verstehe?
Ist es die Funktion oder das Prinzip an sich das ich es total falsch verstehe, bin ratlos.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:03 Uhr.
Seite 1 von 2  1 2      

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