Windohs2000: Heap voll?

Hallo,

vielleicht hier nicht ganz richtig aber evtl. kennt sich jemand mit Speicherverwaltung unter Windows 2000 aus.

Wenn realloc() einen Nullzeiger zurückliefert, ist der Heap voll, so stehts geschrieben. Da Windows angeblich eine dynamische Speicherverwaltung hat und nie voll wird (halte ich für ein Gerücht) wie kann es dann sein, daß ich einen Nullzeiger zurückbekomme? (Speicher doch voll…)

Welche Speicherbereiche werden denn augelagert (Swap), welche nicht?

Li

Hallo,

Wenn realloc() einen Nullzeiger zurückliefert, ist der Heap
voll, so stehts geschrieben. […]

Hast schon mal eine „normale“ Allozierung probiert (wenn der realloc() nicht mehr geht)? Vielleicht hätte er zwar noch Speicher, aber eben nicht zusammenhängend und das Memory Management ist zu blöd um mitzukriegen, dass es mehr Speicher anfordern muss, obwohl weniger verlangt wurde, als insgesamt noch frei ist.

Gruß
Martin

Hallo Li,

Welche Speicherbereiche werden denn augelagert (Swap), welche
nicht?

z.B. der Disk-Cache, macht ja echt keinen Sinn den auf die Platte auszulagern.
Hinzu kommt noch diverser Code, welcher durch den Programmierer gegen AUslagern geschützt werden kann. Da gab es vor allem in früheren Win-Versionen echte Probleme, wenn der Speicher voll war aber die Deinitiallisierungs-outine einer DLL ausgelagert war, dann konnte man das Programm nicht beenden um Speicher freizugeben.

Auch mit diversen API-Aufrufen kann Datenspeicher vor dem Auslagern geschützt werden.

Normalerweise wird deinem Programm ein lokaler einer gewissen Grösse Heap zugewiesen. Dieser Minimal-Wert wird beim Linken festgelegt, kann aber beeinflusst werden.
Wenn der lokale Heap voll ist, wird dann normalerweise vom globalen Heap weiterer Speicher angefordert und der lokale Heap entsprechend vergrössert.

Allerdings kann dir realloc(), besonders wenn man nur um kleine Werte erhöht, den Heap sehr schnell zerstückeln.

MfG Peter(TOO)

Hallo,

vielleicht hier nicht ganz richtig aber evtl. kennt sich
jemand mit Speicherverwaltung unter Windows 2000 aus.

Wenn realloc() einen Nullzeiger zurückliefert, ist der Heap
voll, so stehts geschrieben. Da Windows angeblich eine
dynamische Speicherverwaltung hat und nie voll wird (halte ich
für ein Gerücht) wie kann es dann sein, daß ich einen
Nullzeiger zurückbekomme? (Speicher doch voll…)

Sag niemals nie! :o)

Da Windows ein 32Bit Betriebssystem ist, kann theoretisch 2^32Byte pro Prozess verwalten, das sind 4GByte. Spätestens hier, vermutlich aber wesentlich früher, wird dir der Heapspeicher ausgehen.
Den Heap musst du dir als ein Stück Speicher vorstellen, wenn du ihn vergößerst, so wird hinten etwas angehängt. Der Heap an sich hat keine Lücken und ist linear. Beim AUfruf von alloc sucht sich die Appliktion ein Stück freien Speicher aus dem Heap. Wenn du alloc mehrmals aufrufst, so werden deine Speicherbereiche wahrscheinlich direkt hintereinandere liegen (eine Garantie dafür gibt es nicht). Mit realloc versucht du dein auf dem Heap liegenden Speicher zu vergrößern. Das geht nur, wenn hinter deinem Speicher noch etwas frei ist, liegt dort ein anderer Block, so wird ein völlig neuerer Speicherblock angefordert, der entsprechend die neue größe hat. realloc kopiert dabei den alten Inhalt in den neuen Bereich.
Rufst du immer wiede realloc auf, so fragmentiert dein Speicher, d.h. du hinterlässt eine Lücke und reservierst am Ende des Heaps neuen Speicher. Realloc schläg fehl, sobald keine Lücke mehr existiert, die deinen Speicher-Bedarf befriedigt. Ähnlich sieht das bei malloc aus.
Im worst case allokierst du zig mal ein Byte, da malloc aber immer etwas mehr reserviert, kannst du hiermit deinem kompletten Heap belegen. Gibt es keinen freien Heap-Speicher mehr, geben dir malloc/realloc einen 0-Zeiger zurück.

Man geht von theoretisch unbegrenztem Speicher aus, da kein normale Applikation mehrere GB RAM in Anspruch nimmt. Sollte deine Applikation hier aus der Reihe schlagen, solltest du schleunigst analysieren, wo der Speicher bleibt. Entweder ist deine Applikation sehr Speicherlastig (bedingt durch ein falsches Design), oder sie hat einen Fehler.

Gruß Markus

Den Heap musst du dir als ein Stück Speicher vorstellen, wenn
du ihn vergößerst, so wird hinten etwas angehängt. Der Heap an
sich hat keine Lücken und ist linear. Beim AUfruf von alloc
sucht sich die Appliktion ein Stück freien Speicher aus dem
Heap.

Einspruch! Der Aufruf von alloc veanlasst den Kernel, mir den geforderten Speicher bereitzustellen. Geht das nicht, gibt es den 0-Zeiger. (Ich weiss, Kleinkram in diese Sache)

Sollte
deine Applikation hier aus der Reihe schlagen, solltest du
schleunigst analysieren, wo der Speicher bleibt. Entweder ist
deine Applikation sehr Speicherlastig (bedingt durch ein
falsches Design), oder sie hat einen Fehler.

Einen Fehler habe wir bisher nicht gefunden. Wir suchen ein Tool, was anzeigen kann, wieviel Heap der laufende Prozess gerade belegt und wie es ueber die Laufzeit hinweg (die Anwendung sollte 130 Stunden am Stueck laufen) aussieht. Vermutung war bisher, irgendwo ist RAM defekt oder der Speicher (128 MB) ist wirklich voll. Aber warum nur auf meinem Rechner?

Gibt es so ein Tool?

Li

Hi,

Gibt es so ein Tool?

schätze mal, Du suchst einen Memory Profiler:
http://www.google.de/search?hl=de&q=c+memory+profile…

Gruss,

Herb

Einspruch! Der Aufruf von alloc veanlasst den Kernel, mir den
geforderten Speicher bereitzustellen. Geht das nicht, gibt es
den 0-Zeiger. (Ich weiss, Kleinkram in diese Sache)

Einspruch! malloc, alloc und realloc fordern nicht bei jedem Aufruf
Speicher vom Betriebssystem an. Der Heap ist ein Linearer Speicher,
der durch einen Betriebssystem-Aufruf nach hinten hin erweitert wird.
die alloc-Funktionen verwalten den allokierten Speicher oder rufen
bei Bedarf die Betriebssystemfunktion zum vergrößern des Heaps auf.
Einen 0-Zeiger gibt es erst, wenn im vorhandenen Heap keine Lücke
mehr enthalten ist und der Heap nicht weiter vergrößert werden kann.
BTW die meisten Betriebssysteme kennen nur eine Funktion zum anfordern
von Speicher (UNIX => sbrk()), aber keine Funktion zur Freigabe von
Speicher.

Einen Fehler habe wir bisher nicht gefunden. Wir suchen ein
Tool, was anzeigen kann, wieviel Heap der laufende Prozess
gerade belegt und wie es ueber die Laufzeit hinweg (die
Anwendung sollte 130 Stunden am Stueck laufen) aussieht.
Vermutung war bisher, irgendwo ist RAM defekt oder der
Speicher (128 MB) ist wirklich voll. Aber warum nur auf meinem
Rechner?

Gibt es so ein Tool?

Ein sehr gutes aber auch nicht gerade billiges Tool ist Purify. Zur Fehlersuche verwendest du es statt dem Standard-Linker und erhälst als Ausgabe eine spezielle Debug version. Die erkennt schon zur Laufzeit memory leaks, erkennt darüber hinaus aber noch eine Reihe weiterer Fehler, wie falsche Zugriffe auf den Stack, Free-Memory-Write usw.
Als Open-Source gibt es das mpatrol Tool. Es arbeitet ähnlich wie Purify, also beim Linken, und kann unabhängig von der Programmiersprache beim Linken des Executeables verwendet werden.
Zudem habe ich von einem Tool Insure++ gehört, welches ähnlich wie purify arbeitet und kommerziell ist. Habe damit aber keine Erfahrung.

Gruß Markus