Delphi-PRAXiS
Seite 2 von 6     12 34     Letzte »    

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)

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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:22 Uhr.
Seite 2 von 6     12 34     Letzte »    

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