Freien Arbeitsspeicher ermitteln

Gast #4575692
Lesenswert?

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 #4575722
Lesenswert?

Ü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.
#4575728
Lesenswert?

@ 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 #4575769
Lesenswert?

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 #4575790
Lesenswert?

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 #4575901
Lesenswert?

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) #4576938
Lesenswert?

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) #4577078
Lesenswert?

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) #4577210
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren