Anzeige:
Ergebnis 1 bis 11 von 11

Thema: [c] speicher freigeben

  1. #1
    Registrierter Benutzer
    Registriert seit
    14.01.2002
    Beiträge
    657

    [c] speicher freigeben

    hallo,

    wenn ich mit malloc speicher alloziiert habe kann ich diesen ja mit free
    freigeben. mein problem ist jedoch, dass dieser freie speicher noch
    nicht wirklich an den kernel "zurückgegeben" wird, sondern dass
    das programm (oder isses der kernel?) sich diesen speicher
    in einem malloc-pool zurückhält [1].
    da meine anwendung (serverprozess der sehr lange läuft) jedoch
    zum teil wirklich viel speicherplatz braucht (bis zu 1gb),
    meiste zeit jedoch kaum was, möchte ich, dass das betriebssystem
    diesen speicher nutzen kann.

    wie kann ich also den speicher wirklich freigeben?
    mir ist klar dass bei genügend größer swap größe der speicherbereich (da er nicht genutzt ist) im swap landet, aber das reicht mir nicht.

    danke, Markus

    [1] http://www.hs-augsburg.de/~sandman/c.../c_016_009.htm
    Geändert von msi (12-08-2008 um 21:53 Uhr)

  2. #2
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Also das ist nicht das was ich auf meinem Linux-System in der Praxis beobachte. Das ist in der allgemeinen Formulierung in der es da in dem von dir zitierten Buch steht einfach nur falsch.

    Du brauchst dir da keine Sorgen zu machen - kannst du ja auch ganz einfach ausprobieren indem du ein Progrämmchen schreibst das zwischendurch mal ein paar GB Ram belegt und dir vor/nach der Freigabe den verfügbaren Arbeitsspeicher anschaust.

    Es gibt allerdings sicherlich malloc-Implementierungen, die das so handhaben. Aber auf Desktop- und Serversystemen macht so etwas keinen Sinn und wird deshalb auch nicht so gemacht. (siehe z.B. http://www.ibm.com/developerworks/li...ary/l-memory/] oder auch Wikipedia bzgl des glibc allocators: http://en.wikipedia.org/wiki/Malloc#The_glibc_allocator)

    MfG Peschmä
    Geändert von peschmae (13-08-2008 um 11:14 Uhr)
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  3. #3
    Registrierter Benutzer
    Registriert seit
    14.01.2002
    Beiträge
    657
    habs getestet und der speicher wird leider wirklich nicht freigegeben
    (speicherplatz anzeige via ps), aber wiederverwendet.
    genauso hab ichs beobachtet


    edit in deinem link sthet ja auch:
    "free: This takes a pointer to a segment of memory allocated by malloc, and returns it for later use by the program or the operating system (actually, some malloc implementations can only return memory back to the program, not to the operating system)."

  4. #4
    Registrierter Benutzer
    Registriert seit
    23.05.2007
    Beiträge
    17
    mal ein
    Code:
    watch -n 1 cat /proc/meminfo
    gemacht?
    Und dann verglichen das Prog im anderen Terminal mehrfach zu öffnen und zu schliessen bzw. geschaut ob der Speicher wirklich immer weniger wird?

    Axel

    Obwohl, hat mich ja auch interessiert und mal im Ritchie nachgelesen: Da steht:

    The function free causes the space pointed to ptr to be deallocated. This freed space is usually put into a pool of available memory and can be allocated in a later call to one of the three alloc functions.
    Geändert von gooze (14-08-2008 um 08:48 Uhr)

  5. #5
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Zitat Zitat von msi Beitrag anzeigen
    habs getestet und der speicher wird leider wirklich nicht freigegeben
    (speicherplatz anzeige via ps), aber wiederverwendet.
    genauso hab ichs beobachtet
    Ich hatte das via free beobachtet; aber auch bei ps wird bei mir der Speicher wieder zurückgegeben (ausser ich mache was falsch?)

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
            int* a = (int*) malloc(1024*1024*1024);
            int i = 0;
            for (i = 0; i < 1024*1024*1024/sizeof(int); i++)
                    *(a+i) = i;
    
            printf("malloced 1GB\n");
            getchar();
    
            free(a);
            printf("freed 1 GB\n");
            getchar();
    
            return 0;
    }
    Nach dem malloc:
    Code:
    peschmae@sid:/tmp$ ps -aux | grep test
    USER           PID   %CPU %MEM   VSZ      RSS       TTY   STAT START  TIME COMMAND
    peschmae 4870 10.2 25.8 1052228 1049008 pts/3 S+   10:53   0:03 ./test
    und nach dem free:
    Code:
    peschmae 4870  8.4  0.0   3648   432 pts/3    S+   10:53   0:03 ./test
    edit in deinem link sthet ja auch:
    "free: This takes a pointer to a segment of memory allocated by malloc, and returns it for later use by the program or the operating system (actually, some malloc implementations can only return memory back to the program, not to the operating system)."
    Some malloc implementation steht da, aber in Wikipedia steht dass die von GLibc den Speicher zurückgeben kann.

    MfG Peschmä
    Geändert von peschmae (14-08-2008 um 10:00 Uhr)
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  6. #6
    Registrierter Benutzer
    Registriert seit
    23.05.2007
    Beiträge
    17
    ich muss msi aber rechtgeben.
    Der Speicher wird auf dem Heap wieder für malloc und Co wieder freigegeben, aber dem Kernel steht der Space dann nicht mehr zur Verfügung. Jedenfalls sagt der Ritchie das auch ein paar Absätze weiter.

    Axel

  7. #7
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Naja, Ritchie ist ja wohl nicht die Referenz in Bezug auf die GNU Libc. Ausserdem sagt er "usually".

    Die GLibc Doku sagt schwammig:
    Zitat Zitat von Doku
    Occasionally, free can actually return memory to the operating system and make the process smaller. Usually, all it can do is allow a later call to malloc to reuse the space. In the meantime, the space remains in your program as part of a free-list used internally by malloc.
    http://www.gnu.org/software/libc/man...g-after-Malloc

    Etwas klarer wird die Geschichte wenn man da guckt: http://www.gnu.org/software/libc/man...ble-Parameters

    Zitat Zitat von Doc
    M_TRIM_THRESHOLD
    This is the minimum size (in bytes) of the top-most, releasable chunk that will cause sbrk to be called with a negative argument in order to return memory to the system.
    sbrk ist das Dingens das Malloc benutzt um Speicher vom System zu kriegen/zurückzugeben.

    So wie ich das verstehe muss der Adressbereich obenrum frei sein damit sbrk den Speicher zurückgeben kann, was natürlich nicht zwingend der Fall ist auch wenn du die meisten der mit malloc angeforderten Speicherbereiche wieder freigegeben hast.

    M_MMAP_THRESHOLD
    All chunks larger than this value are allocated outside the normal heap, using the mmap system call. This way it is guaranteed that the memory for these chunks can be returned to the system on free. Note that requests smaller than this threshold might still be allocated via mmap.
    Für mein Testprogramm wurde der Speicher also sofort zurückgegeben weil 1 GB natürlich viel grösser ist als der Wert den M_MMAP_THRESHOLD hat. Was auch immer das sein mag...

    MfG Peschmä
    Geändert von peschmae (14-08-2008 um 12:07 Uhr)
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  8. #8
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Ich habe noch mal schnell ein kleines Testprogrämmchen geschrieben um zu überprüfen ob ich die Doku richtig verstanden habe.

    Folgendes:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
            const int len = 1024*1024;
            void **a = (void**)malloc(len*sizeof(void*));
            int i;
            for (i = 0; i < len; i++)
                    a[i] = (void*)malloc(1024);
    
            void* blocker = malloc(100);
    
            printf("malloced 1GB\n");
            getchar();
    
    
            for (i = 0; i < len; i++)
                    free(a[i]);
            printf("freed 1 GB\n");
            getchar();
    
    
            free(blocker);
            printf("freed blocker\n");
            getchar();
    
            return 0;
    }
    a ist ein Pointer-Array. In der For-Schleife werden für die 1024*1024 Pointer in a jeweils 1024 Byte alloziert. Insgesamt 1 GB. Die 1024 Bytes sind jeweils so klein dass mmap nicht benutzt wird.

    Nach den mallocs ist der Speicher voll:
    Code:
    peschmae     6562  4.8 26.4 1076820 1073588 pts/5 S+   13:20   0:00 ./test
    In einem nächsten Schritt werden weitere 100 Bytes alloziert - die sind (offenbar) zuoberst auf dem Heap. Anschliessend werden die 1 GB Speicher die zu den Pointern in a gehören wieder freigegeben. Nachher ist der Speicher immer noch belegt:
    Code:
    peschmae     6562  4.6 26.4 1076820 1073592 pts/5 S+   13:20   0:00 ./test
    Was daran liegt dass die oberste Adresse auf dem Heap vom Speicher in blocker belegt ist - die 1 GB darunter sind zwar frei, können aber mit sbrk nicht ans OS zurückgegeben werden weil sbrk nur die Heap-Obergrenze dynamisch verschieben kann.

    Das geht erst wenn auch der blocker-Speicher weg ist:
    Code:
    peschmae     6562  4.3  0.2  11976  8760 pts/5    S+   13:19   0:01 ./test
    Fazit in Bezug auf die Ausgangsfrage: Es scheint als müsstest du sicherstellen dass du wirklich allen Speicher wieder freigibst der oben auf dem Heap ist (d.h. spät alloziiert wurde - wobei der Zusammenhang zwischen spät alloziiert und oben auf dem Heap ja nicht zwingend ist), damit der Speicher wieder ans OS zurückgegeben werden kann.

    Oder genug grosse Speicherblöcke benutzen, damit mmap benutzt wird. Oder die Limits ändern dass häufiger mmap benutzt wird (wobei sich dann die Frage stellt ob das nicht plötzlich ineffizient wird - z.B. wegen Verwaltungsaufwand oder ob die Memory-Mapping-Tabellen irgendwo in ihrer Grösse beschränkt sind (läuft das eventuell in Hardware?); irgend einen Grund wird es schon haben dass die Methode normalerweise nur für grössere Speicherblöcke verwendet wird)

    Interessanter Kommentar zum Thema: http://c-faq.com/malloc/free2os.es.html

    MfG Peschmä
    Geändert von peschmae (14-08-2008 um 12:36 Uhr)
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  9. #9
    Registrierter Benutzer Avatar von undefined
    Registriert seit
    01.03.2004
    Beiträge
    1.255
    Wenn der Speicher vom Kernel nicht frei gegeben wird liegt es daran das die last deines Programms zu hoch ist.
    Ein paar Infos zu dem Thema.
    malloc ist Userspace und nicht Kernel, der Kernel kennt kein malloc sondern kmalloc und das ist nicht Userspace Der Kernel verwaltet den Speicher unabhängig des laufenden Programms (Preemptives verhalten). Der Kernel sieht einfach nach wer wo wann und wie viel verbraucht in legt die reservierung fest. Wenn die last beständig hoch (viele veschiedene Prozesse auf eine Schnittstelle) ist wird ein SLAB/SLUB Layer angelegt und der ist erst mal save. Siehe ls /proc/slabinfo oder mein Programm kcmslabinfo
    Alleine dieses Thema verbraucht im Linux Kernel Handuch Buch 100 Seiten und ich habe es bis jetzt noch nicht ganz geschnallt. Außerdem kann man so wenig schreiben weil keiner weiss wie du deine Schnittstelle geschrieben hast.
    Es gibt gerade für Netzwerk Schnittstellen im Kernel gesonderte bereiche.
    Hier die Doku ist auch ganz gut http://www.oreilly.de/german/freeboo...e2ger/get.html
    mfg undefined
    --
    Undefined Behavior (undefiniertes Verhalten) bedeutet meistens etwas ungültiges.
    xhtml Debugger

  10. #10
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Das was peschmae da getestet hat klingt interessant, den Java KANN mit so einer Situation umgehn. Java weiß wo "Pointer" auf einen Speicher liegen und somit kanns den Speicher verschieben und alle Pointer anpassen. Von dem her ist der Garbagecollector wesentlich Speichereffizienter.
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

  11. #11
    Registrierter Benutzer
    Registriert seit
    14.01.2002
    Beiträge
    657
    danke euch allen. Das Problem ist, wie peschmae im 2. Post geschrieben hat, dass eben nur speicher freigegeben wird, der "in der mitte" des heaps liegt.
    werde mal schauen wie ich das anpasse.
    danke!

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •