Forum: PC-Programmierung malloc() schlägt zurück.


von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Servus,

malloc() weigert sich, mir 1,45 GB Speicher herauszurücken obwohl
lt. Taskmanager noch 2,6 GB "physikalischer" frei seien. Irgendwie
verstehe ich nicht warum. Ist unlogisch und einfach lästig.

System: Win XP prof SP3

Grüße Joe.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dann verwende doch die Win32-API-Funktionen zur Speicherverwaltung und 
nicht die der C-Runtime-Umgebung.

Dann gibt es möglicherweise auch etwas ausführlichere Fehlermeldungen.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366597%28v=vs.85%29.aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887%28v=vs.85%29.aspx

Ansonsten ist der für einen Prozess zur Verfügung stehende Speicher 
unter 32-Bit-Windows üblicherweise auf insgesamt 2 GiB beschränkt, das 
gilt es zu berücksichtigen. Es gibt aber eine Bootoption, dieses Limit 
auf 3 GiB anzuheben:

http://msdn.microsoft.com/en-us/library/windows/hardware/ff556232%28v=vs.85%29.aspx

von Peter II (Gast)


Lesenswert?

zu der aussage von   Rufus Τ. Firefly kommt nach dazu, das der Speicher 
am stück frei sein muss. Wenn in der mitte bereits etwas ist dann geht 
es auch schief. (Fragmentierung).

1,5GB am stück auf einem 32Bit System wird wohl nie sauber 
funktionieren.

von Alexander B. (leuchte)


Lesenswert?

malloc ist außerdem nicht für solche "Speicheranfragen" gedacht. Eher 
für Blöcke <= 1MByte. VirtualAlloc ist das, was du suchst. Insbesondere 
die Address Windowing Extensions (siehe 
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366527(v=vs.85).aspx 
).

von Peter II (Gast)


Lesenswert?

Alexander B. schrieb:
> malloc ist außerdem nicht für solche "Speicheranfragen" gedacht.

warum sollte das so sein? Es läuft am ende sowieso auf VirtualAlloc 
hinaus. Die Limits sollte bei beiden gleich sein. Nur kann man bei 
VirtualAlloc mehr Optionen angeben.

von Alexander B. (leuchte)


Lesenswert?

Peter II schrieb:
> warum sollte das so sein?

Weil malloc und HeapAlloc ihren Heap fragmentieren, wie du oben schon 
richtig bemerkt hast. Wenn man weiß, dass man knapp 1,5GByte haben will 
und die Umgebung, in der das Programm läuft nicht kennt, schießt man 
sich mit einer fragmentierenden Speicherverwaltung schnell selbst in den 
Fuß.

von Peter II (Gast)


Lesenswert?

Alexander B. schrieb:
> Weil malloc und HeapAlloc ihren Heap fragmentieren, wie du oben schon
> richtig bemerkt hast. Wenn man weiß, dass man knapp 1,5GByte haben will
> und die Umgebung, in der das Programm läuft nicht kennt, schießt man
> sich mit einer fragmentierenden Speicherverwaltung schnell selbst in den
> Fuß.

da aber der Rest vom Programm (new) auch malloc verwendet, ist der 
Speicher eh fragmentiert. Dann bringt es auch nichts den großen block 
mit VirtualAlloc zu holen. Wenn malloc den block nicht bekommt, dann 
bekommst du ihn auch mit VirtualAlloc nicht.

Sinnvoller ist wohl gleich auf 64bit zu gehen.

von Alexander B. (leuchte)


Lesenswert?

Peter II schrieb:
> Wenn malloc den block nicht bekommt, dann
> bekommst du ihn auch mit VirtualAlloc nicht.

Eben da kommen die Address Windowing Extensions in Spiel (Link s.o.), 
entsprechend viel physikalischer Speicher vorrausgesetzt.

> Sinnvoller ist wohl gleich auf 64bit zu gehen.

Natürlich! Das steht schon fast außer Frage.

Und dass malloc fehlschlägt, weil VirtualAlloc im den Speicher 
verweigert ist nur eine Vermutung. malloc nutzt erstmal HeapAlloc und 
dieser den "process heap". Dieser kann künstlich begrenzt sein. Die 
Doku zu HeapCreate sagt, wie das geht.

von Bastler (Gast)


Lesenswert?

Ein Prozess unter Win32 hat 2(, als Server mit Konfigurationstricks max. 
3) GB Adressraum.
Von den vermutlich 2GB geht noch Platz für Shared Memory, z.B. div. 
DLL's ab.
Der angezeigte freie Speicher ist physisches RAM, das nicht dauerhaft 
von virtuellen Adressräumen benutzt wird. Das kann dank PAE auch bei 
Win32 mehr als 4GB sein, aber die Verwaltung eines solchen Systems 
erinnert etwas an Banking. (Die Älteren wissen, daß das nix mit Geld zu 
tun haben muß)
Bei einem 64Bit Windows würdest du den Speicher bekommen, einfach weil 
der Adressraum je Prozess (nein nicht 2^63, aber mWn mindestens) 128GB 
groß ist. Ob soviel RAM überhaupt da ist, interessiert nicht Dank 
Paging. Das ist BTW auch ein wichtiger Grund für 64Bit. Neben 16x64Bit 
statt 8x32BitRegistern und damit auch modernerem Befehlssatz. Die oft 
gehörte Meinung bis 4GB geht es gut mit 32Bit-OS ist schlicht falsch.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Anheben der 3 GB-Grenze ? Mutig ... :-)))

Ich rege mich nur auf. Einen Workaround muß ich eh bauen.
Halt die Größe der zu sortierenden Dateien reduzieren.

Ich probiere halt mal herum was das so packt ...

PS: Ich bekomme keine Benachrichtigung per Mail wenn hier
jemand postet. Die "Benachrichtigung" ist eingeschaltet und
andere Mails bekomme ich auch. Also läuft der Mailserver.
Ich bekomme auch die Option "E-Mail-Benachrichtigung abschalten"
präsentiert ?

von Uhu U. (uhu)


Lesenswert?

Joachim Drechsel schrieb:
> Halt die Größe der zu sortierenden Dateien reduzieren.

Oder einen geeigneten Sortierer benutzen - es gibt nämlich seit Urzeiten 
welche, die Dateien sortieren, die vielfach so groß sind, wie der 
Arbeitsspeicher.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Uhu Uhuhu schrieb:
> Oder einen geeigneten Sortierer benutzen - es gibt nämlich seit Urzeiten
> welche, die Dateien sortieren, die vielfach so groß sind, wie der
> Arbeitsspeicher.

qsort() halt.

von Bastler (Gast)


Lesenswert?

Die 3GB Grenze kann man durch Verwendung von Win64 aufheben. Dann die zu 
sortierende Datei in den Speicher mappen und qsort'ieren. Wenn' ohne 
großen Aufwand gehen soll, dann Java's NIO Lib ausprobieren. Die kann so 
was ohne seltsame OS-API's. Wenn's dann geht, kann man immer noch die 
sperrige WinNT-API bemühen. Geht bis einige GB Dateigröße.

von Peter II (Gast)


Lesenswert?

oder einfach nicht eine Liste mit Objekten sondern Zeiger auf Objekte 
verwenden. Dann braucht jedes Objekt seinen eigenen Speicher. Damit 
brauch man keinen großen block.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Peter II schrieb:
> Wenn in der mitte bereits etwas ist dann geht
> es auch schief. (Fragmentierung).

Das ist unter 32-Bit-Windows kein großes Problem, denn jeder Prozess 
sieht seinen eigenen Speicher, mit eigenen Speicheradressen -- solange 
nicht der Prozess sich selbst seinen Speicher fragmentiert hat, gibt es 
das Problem also nicht.

Ob der physikalische Speicher fragmentiert ist oder nicht ist völlig 
irrelevant, die physikalischen Adressen bekommt ein normaler Prozess 
sowieso nicht vorgesetzt, das geht alles über die MMU.

von Peter II (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> solange
> nicht der Prozess sich selbst seinen Speicher fragmentiert hat, gibt es
> das Problem also nicht.

das alleine reicht schon. Es reicht ja schon wenn er 600MB mit realloc 
auf 1,5GB aufblasen will.

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Mal prinzipiell: Was ist von einem OS zu halten das behauptet
es hätte 2,6 GB Speicher frei und dann 1,5 GB nicht hergibt ?
Sinn eines OS ist ja unter Anderem auch die Verwaltung der
Betriebsmittel ...

von Konrad S. (maybee)


Lesenswert?

Du könntest dir den Speicher besorgen, bevor das große Fragmentieren 
losgeht.

von Peter II (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> Mal prinzipiell: Was ist von einem OS zu halten das behauptet
> es hätte 2,6 GB Speicher frei und dann 1,5 GB nicht hergibt ?
> Sinn eines OS ist ja unter Anderem auch die Verwaltung der
> Betriebsmittel ...

Wenn du denkst das ist bei irgend einem andere BS anders. Dann hast du 
wenig Ahnung davon.

von Bastler (Gast)


Lesenswert?

Von den 2GB, die er hat, gehen noch diverse Stack, DLL, ... Bereiche ab. 
Dies sind nicht unbedingt "gepacked" abgelegt, sondern haben große 
Lücken, sind also fragmentiert. 1,5 GB am Stück in einem 2GB Adressraum 
zu finden ist mutig.

von Konrad S. (maybee)


Lesenswert?

Joachim Drechsel schrieb:
> Mal prinzipiell: Was ist von einem OS zu halten das behauptet
> es hätte 2,6 GB Speicher frei und dann 1,5 GB nicht hergibt ?
> Sinn eines OS ist ja unter Anderem auch die Verwaltung der
> Betriebsmittel ...

Es fehlt ja nicht an Speicher, sondern an Adressraum. Das Problem ist 
mir vom MacOS her aber auch schon bekannt. Und unter Linux oder anderen 
Unixen kannst du ins gleiche Problem laufen.

von Peter II (Gast)


Lesenswert?

Bastler schrieb:
> Dies sind nicht unbedingt "gepacked" abgelegt, sondern haben große
> Lücken, sind also fragmentiert. 1,5 GB am Stück in einem 2GB Adressraum
> zu finden ist mutig.

sogar mit Absicht werden die lücken geschaffen:

http://en.wikipedia.org/wiki/Address_space_layout_randomization

von Bastler (Gast)


Lesenswert?

@J.D.: wenn man verstanden hat, wie ein modernes OS seinen Speicher 
verwaltet, dann ist das das kein Widerspruch. Virtueller Adressraum != 
Physikalischer Adressraum. Und x86 kann mehr als 4GB physikalisch 
ansprechen, ein 32Bit-OS kann die per Banking-Tricks sogar komplett 
nutzen. Nur kann es keinem Prozess mehr als 2(3)GB virtuell geben.
Win32 hat aber so viel ich weiß eine API um Physische Speicher in 
Fenster im Adressraum einzublenden. Hat man mal gebraucht, als es noch 
keine 64Bit CPU's gab. Wer das heute noch benutzt, schläft auch auf 
Nagelbrettern ;-)

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Bastler schrieb:
> @J.D.: wenn man verstanden hat, wie ein modernes OS seinen Speicher
> verwaltet, dann ist das das kein Widerspruch. Virtueller Adressraum !=
> Physikalischer Adressraum. Und x86 kann mehr als 4GB physikalisch
> ansprechen, ein 32Bit-OS kann die per Banking-Tricks sogar komplett
> nutzen. Nur kann es keinem Prozess mehr als 2(3)GB virtuell geben.
> Win32 hat aber so viel ich weiß eine API um Physische Speicher in
> Fenster im Adressraum einzublenden. Hat man mal gebraucht, als es noch
> keine 64Bit CPU's gab. Wer das heute noch benutzt, schläft auch auf
> Nagelbrettern ;-)

Geht ja nicht mal um > 2GB.

Ich habe die Datenmenge jetzt mal halbiert, dann geht es.

Ich schlafe auf Nagelbrettern, fahre ein russisches Gespann,
trinke gerne Bier, rauche und verwende Win32. Mit einem 6502 und
geeigneter Hardware (Adresslatchgrab) ziehe ich da auch 64 GB RAM
durch ;)

von Jens G. (jensig)


Lesenswert?

@ Alexander B. (leuchte)

>Peter II schrieb:
>> Wenn malloc den block nicht bekommt, dann
>> bekommst du ihn auch mit VirtualAlloc nicht.

>Eben da kommen die Address Windowing Extensions in Spiel (Link s.o.),
>entsprechend viel physikalischer Speicher vorrausgesetzt.

AWE liefert auch keinen größeren Arbeitsspeicherblock am Stück - das ist 
eher Speicher bzw. eine Krücke zum Auslagern von Daten in andere, sonst 
nicht zugreifbare Speicherbereiche oberhalb 4GB. Wie zu DOS-Zeiten der 
EMM ...

von Uhu U. (uhu)


Lesenswert?

Joachim Drechsel schrieb:
> qsort() halt.

qsort ist für derartige Brocken nicht gerade die erste Wahl.

Laß die Daten von einem externen Mergesort sortieren und lies das 
Ergebnis dann ein.

http://stackoverflow.com/questions/7361074/how-can-i-sort-large-csv-file-without-loading-to-memory

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Uhu Uhuhu schrieb:
> Joachim Drechsel schrieb:
>> qsort() halt.
>
> qsort ist für derartige Brocken nicht gerade die erste Wahl.
>
> Laß die Daten von einem externen Mergesort sortieren und lies das
> Ergebnis dann ein.
>
> 
http://stackoverflow.com/questions/7361074/how-can-i-sort-large-csv-file-without-loading-to-memory

Geht in diesem Fall nicht. Es sind Records a 25 Byte (feste Satzlänge).
Mehrfache fliegen dabei heraus.

von Uhu U. (uhu)


Lesenswert?

Oder such dir einen Quelltext für ein Mergesort und paß ihn für dich an. 
Feste Satzlängen sind doch prima.

von Arc N. (arc)


Lesenswert?

Uhu Uhuhu schrieb:
> Oder such dir einen Quelltext für ein Mergesort und paß ihn für dich an.
> Feste Satzlängen sind doch prima.

Auch wenn ich mich ebenso nur an ein paar Mergesort-Varianten erinnern 
kann, wäre das Stichwort für die Suchmaschine: Externes Sortieren

von Alexander B. (leuchte)


Lesenswert?

Jens G. schrieb:
> AWE liefert auch keinen größeren Arbeitsspeicherblock am Stück - das ist
> eher Speicher bzw. eine Krücke zum Auslagern von Daten in andere, sonst
> nicht zugreifbare Speicherbereiche oberhalb 4GB. Wie zu DOS-Zeiten der
> EMM ...

Danke, die Dokumentation kann ich auch lesen. ^^
Es ist lediglich eine Methode das Ausgangsproblem zu umgehen. Die 
anderen, nämlich für 64-bit bauen oder seinen Algorithmus so zu ändern, 
dass er weniger Speicher benötigt, wurden auch schon genannt. Eigentlich 
ist das Thema damit abgehakt.

Joe könnte ja mal mit mehr Details zu seinem Problem herausrücken.
Vorausgesetzt seine auferlegte Geheimhaltungsstufe ist dafür nicht all 
zu hoch...

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Alexander B. schrieb:
> Joe könnte ja mal mit mehr Details zu seinem Problem herausrücken.
> Vorausgesetzt seine auferlegte Geheimhaltungsstufe ist dafür nicht all
> zu hoch...

Gerne ;)

Ich archiviere größere Datenmengen, eins der System ist eine
selbstgebaute Datenbank. Momentan sind's beim größten Kunden
ca 650 GB pro Jahr (ist nach Jahren aufgeteilt).

Um darauf schnell zugreifen zu können habe ich 4 Indices, im Prinzip
Tabellen in entsprechender Sortierung über die ich passende finde
(alphabetisch sortiert, nach ca 8-10 Vergleichen habe ich den
ersten Treffer).

Im konkreten Fall habe ich Rohdaten mit ingsgesamt 140 Mio Records
a 25 Bytes die sortiert werden.

Damit es mir den Rechner nicht sprengt mache ichdas teilweise.
Die Records werden in dann schon erheblich handlichere temporäre
Dateien aufgeteilt (jeweils das erste Zeichen geht in den Dateinamen
en). Dabei ergab sich jetzt eine mit 1,45 GB (da ist dann auch das
Problem aufgetreten).

Abhilfe war, die temporären Dateien zu verkleiner. Statt einer
Datei mit 1,45 GB sind es jetzt 2 mit jeweils der Hälfte.

Danke für die vielen Hinweise !

von DirkZ (Gast)


Lesenswert?

Joachim Drechsel schrieb:
> Mal prinzipiell: Was ist von einem OS zu halten das behauptet
> es hätte 2,6 GB Speicher frei und dann 1,5 GB nicht hergibt ?
> Sinn eines OS ist ja unter Anderem auch die Verwaltung der
> Betriebsmittel ...

Virescanner installiert? Der belegt auch Hauptspeicher, dessen Belegung 
nicht angezeigt wird.

von Rolf Magnus (Gast)


Lesenswert?

Bastler schrieb:
> Von den vermutlich 2GB geht noch Platz für Shared Memory, z.B. div.
> DLL's ab.

Ich dachte immer, die 2GB-Grenze statt einer 4GB-Grenze gibt es gerade 
deshalb, weil die anderen 2GB schon für Shared Memory reserviert sind.

Joachim Drechsel schrieb:
> Mal prinzipiell: Was ist von einem OS zu halten das behauptet
> es hätte 2,6 GB Speicher frei und dann 1,5 GB nicht hergibt ?

Hergeben tut es die schon, nur eben nicht in einem Stück.

> Sinn eines OS ist ja unter Anderem auch die Verwaltung der
> Betriebsmittel ...

Was soll es denn deiner Meinung nach tun, um einen so großen Block am 
Stück bereitzustellen?

DirkZ schrieb:
> Virescanner installiert? Der belegt auch Hauptspeicher, dessen Belegung
> nicht angezeigt wird.

Mich beschleicht in letzter Zeit das Gefühl, daß Virenscanner den 
Schädlingen, die sie eliminieren sollen, immer ähnlicher werden.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Mich beschleicht in letzter Zeit das Gefühl,

Mich beschleicht das Gefühl das hier Physikalischer Speicher, Virtueller 
Speicher und Prozessspeicher durcheinandergewürfelt werden. Das 
Virenscanner Speicher innerhalb eines User-Prozesses belegen wäre mir 
zumindest neu...

von Jens G. (jensig)


Lesenswert?

@ Rolf Magnus (Gast)

>Bastler schrieb:
>> Von den vermutlich 2GB geht noch Platz für Shared Memory, z.B. div.
>> DLL's ab.

>Ich dachte immer, die 2GB-Grenze statt einer 4GB-Grenze gibt es gerade
>deshalb, weil die anderen 2GB schon für Shared Memory reserviert sind.

Nee - die anderen 2GB sind für den Kernel reserviert. Kann man bei den 
höherwertigen Windowseditionen mit dem /3GB Switch in der boot.ini aber 
auf 1GB reduzieren, um 3GB für den Userspace zu bekommen

von Cyblord -. (cyblord)


Lesenswert?

Joachim Drechsel schrieb:
> Uhu Uhuhu schrieb:
>> Oder einen geeigneten Sortierer benutzen - es gibt nämlich seit Urzeiten
>> welche, die Dateien sortieren, die vielfach so groß sind, wie der
>> Arbeitsspeicher.
>
> qsort() halt.

Ne, klassischer QuickSort sortiert im Ram. Aber es gibt z.B. "External 
merge sort", welcher in Datenbanken zum Einsatz kommt und das kann.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.