Freien Arbeitsspeicher ermitteln

Gast #4575692
Hi,

ich habe hier ein kleines Embedded-Board das ohne MMU oder virtuellem 
Speicher daherkommt und rein bare-metal in ANSI-C programmiert wird. Der 
zu benutzende Speicher wird in meiner Applikation zu Beginn einmalig mit 
diversen malloc()s alloziiert.

Jetzt habe ich folgendes Problem: Über das Linker-Command-File ist der 
Heap mit einer bestimmten Größe festgelegt. Wie viel Speicher durch die 
verschiedenen malloc()s geholt wird, kann ich mir ausrechnen und auf 
Basis dessen ermitteln, wie viel da tatsächlich noch übrig ist.

Aber: ich hätte gerne eine Möglichkeit, um beides zu verifizieren - ob 
meine Heap-Definition im Linkerfile und meine angenommene 
Speicherbelegung richtig ist.

Wie kann ich das (gerne auch nur in einer DEBUG-Version, die nicht 
ausgeliefert wird) am besten machen?

Gibt es eine ANSI-C-Funktion, welche mir in so einem Szenario den noch 
verfügbaren Heap ausspuckt?

Danke!
Gast
Üblicherweise laufen Stack und Heap aufeinander zu. Du vergleichst dann 
einfach die Adressen der lokalen Variablen mit den Pointern, die 
malloc() liefert.

Kannst auch eine kleine Test-Funktion schreiben, die rekursive Aufrufe 
und mallocs() macht, bis die Grenzen erreicht sind. Normalerweise 
überschreibt der Stack ohne jede Warnung den Heap.
@ Donk (Gast)

>zu benutzende Speicher wird in meiner Applikation zu Beginn einmalig mit
>diversen malloc()s alloziiert.

Dann braucht man auch kein malloc sondern kann alle Speicherbereiche 
statisch als globale Variablen definieren, dann sieht man auch direkt 
wieviel Speicher beötigt wird.
Gast
Falk B. schrieb:
> Dann braucht man auch kein malloc sondern kann alle Speicherbereiche
> statisch als globale Variablen definieren, dann sieht man auch direkt
> wieviel Speicher beötigt wird.

Es sei denn ich habe dynamisch unterschiedliche Konfigurationen, die ich 
erst beim Booten ermitteln kann und die jeweils andere Speichergrößen 
benötigen.
Gast
U. F. schrieb:
> Und auch dann kann man meist mit fixen Strukturen und Union arbeiten

In diesem Fall geht es um Ringbuffer mit unterschiedlichen Größen und 
unterschiedlichen gepufferten Strukturen. Klar, irgendwie kann man alles 
immer irgendwie in Unions mit Arrays mit verschachtelten Strukturen mit 
eingebetteten Hühnerknochen mit gecastetem Schneckenschleim verfrickeln, 
aber das Ganze soll ja auch noch les- und wartbar bleiben.

Und da sind ein paar mallocs() ausschließlich am Programmstart meiner 
Meinung nach das weitaus kleinere Übel.
Gast
Ich würde auch mit malloc antesten, wie viel Speicher zu belegen kannst 
- allerdings in einer Schleife, nicht nicht rekursiv.

Fange mit der maximalen RAM Größe minus 1/8 an. Wenn das geht, gib den 
Speicher wieder frei un liefere die Größe als Testergebnis zurück. Wenn 
es nicht geklappt hat, reduziere den Wert wieder um 1/8. So tastest du 
dich schrittweise an den richtigen Wert heran, wobei die Schritte immer 
kleiner werden.

Abbruchbedingung für die Schleife: Wenn die Zahl nach dem Subtrahieren 
kleiner als 8 ist, breche den test ab und melde "RAM voll".

Bedenke, dass das freie RAM auch fragmentiert sein kann. Mit dieser 
Schleife erhälst du (ungefähr) den größten Zusammenhängenden Block. 
Darüber hinaus könnten aber auch noch kleinere Speicherblöcke verfügbar 
sein. Für eine grobe Abschätzung, ob genug RAM frei ist, reicht das 
meistens jedoch.
(Firma: Torrox.de)
Dann kannst Du Dir Dein malloc auch ganz einfach selbst schreiben, in 
dem Du einen Zeiger auf den Anfang des heaps initialisiert und mit jeder 
Allozierung um den allozierten Speicher weiter bewegst. Die Differenz 
zwischen dem Zeiger und dem Ende des Heaps ist dann der noch freie 
Speicher.

Alles andere ist nur gerate und hängt sehr stark von der Implementierung 
des Heaps ab.
(Firma: Torrox.de)
Dumdi D. schrieb:
> Torsten R. schrieb:
>> in
>> dem Du einen Zeiger auf den Anfang des heaps initialisiert
>
> wie macht man das (Code)?

in etwa so, wenn Du den heap zwischen __HEAP_START und __HEAP_END legst.
1
#include <stdlib.h>
2

3
extern char __HEAP_START;
4
extern char __HEAP_END;
5

6
static char const * heap_end = &__HEAP_END;
7
static char const * heap_top = &__HEAP_START;
8

9
void* allocate_memory( size_t s )
10
{
11
    void* result = 0;
12

13
    if ( heap_end - heap_top >= s )
14
    {
15
        result = (void*)heap_top;
16
        heap_top += s;
17
    }
18

19
    return result;
20
}
(Firma: Torrox.de)
Stefan U. schrieb:
> Im Fall von AVR unf svg-gcc geht das so nicht. Denn dort beginnt der
> Heap an einem Ende des Speichers und der Stack am anderen Ende. Wenn sie
> wachsen, treffen sich Heap und Stack irgendwo in der Mitte. Beide
> Speicherbereiche haben keine feste Größe.

Das ist bei sehr vielen Controllern so. Selbst wenn head und stack keine 
von Dir fest definierte Größe haben, wirst Du Dir Gedanken darüber 
machen wollen, wie groß Dein Stack sein muss.

Und nach dem Du Dir die Gedanken gemacht hast, hält Dich auch niemand 
davon ab, dem Stack eine feste Größe zu geben. Der Rest ist dann 
statischer Speicher plus Heap.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.