Repository 32bit  Forum
Repository 64bit  Wiki

[C] free

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

[C] free

Messaggioda Dani » lun giu 02, 2008 14:31

La memoria allocata con malloc/calloc/realloc quando viene liberata con free è immediatamente riutilizzabile dal sistema operativo ?
Ho una funzione che alloca diversi megabytes con malloc e prima di ritornare il controllo alla funzione chiamante libera il tutto. Il problema è che questo non sembra accadere !
Ho messo un getchar() subito dopo i free(), aperto un terminale con un "free -m -s .4" in loop e noto sorprendentemente che la memoria non risulta libera finchè il programma non viene terminato !?
Com'è possibile questo considerando che il programma non ha memory leak ?
Credo di essermi perso qualcosa :|
Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch

Re: [C] free

Messaggioda Mario Vanoni » lun giu 02, 2008 15:03

Dani ha scritto:La memoria allocata con malloc/calloc/realloc quando viene liberata con free è immediatamente riutilizzabile dal sistema operativo ?
Ho una funzione che alloca diversi megabytes con malloc e prima di ritornare il controllo alla funzione chiamante libera il tutto. Il problema è che questo non sembra accadere !
Ho messo un getchar() subito dopo i free(), aperto un terminale con un "free -m -s .4" in loop e noto sorprendentemente che la memoria non risulta libera finchè il programma non viene terminato !?
Com'è possibile questo considerando che il programma non ha memory leak ?
Credo di essermi perso qualcosa :|


Vecchia discussione,
UNIX/Linux usa fino all'esaurimento tutta la memoria a disposizione,
free(3) libera quella del tuo programma, ma non la totale.
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: [C] free

Messaggioda Dani » lun giu 02, 2008 15:23

E io quella del mio programma voglio liberare !

1) free -m | grep "cache:" | awk '{print $3'} dice 226
2) avvio il programma
3) free dice sempre 226
4) viene chiamata una funzione che alloca della memoria, facciamo 10 mega
5) free dice 236
6) la funzione che ha allocato la memoria finisce di lavorare, chiama free() per ogni malloc/calloc/realloc e ritorna
7) free vede ancora 236 mega occupati
8) il programma termina
9) free ora dice 226 ...

Idem con top,
$ top -d 0.5 -p `pidof programma`

Dal momento dell'allocazione alla terminazione del programma vede sempre una percentuale costante di memoria usata, in pratica e' come se le chiamate a free() non avessero effetto !
Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch

Re: [C] free

Messaggioda robbybby » lun giu 02, 2008 15:29

Se allochi, per esempio, 10 byte (malloc(10)), la malloc non chiede 10 byte al sistema operativo, ma ne chiede di piu' (per esempio una pagina, che su i386 e Linux e' 4k). Questo per evitare un'eccessiva frammentazione dell'heap, e un rallentamento del programma.
Al successivo malloc di pochi byte, il tuo programma non richiedera' la memoria al Sitema Operativo, ma ne utilizzera' un altro po' di quella allocata in precedenza.
Questo per allocazioni piccole.
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1176
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5

Re: [C] free

Messaggioda Mario Vanoni » lun giu 02, 2008 16:44

Da un vecchio libro C del 1987, quindi UNIX:

voce free

although your program will never get smaller using free -
that is, free will not "shrink" the size of a process

finche' c'e` memoria, il tuo programma rimane in memoria,
qualora tu lo richiamassi per essere subito disponibile

questo e` normalissimo per UNIX, e quindi per Linux

mettiti il cuore in pace, dei 4GB sulla mia macchina,
guardando top, rimangono forse 33M free, poi risale a 130M

test: cd / ; find -exec wc {} \;

Ctrl-C per terminare, top: 130M free

rifatto il test sopra: rimane sempre sui 130M free
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: [C] free

Messaggioda Dani » lun giu 02, 2008 17:06

E cosa accade alla memoria bufferizzata qualora un nuovo processo desideri allocarne altra per se ?

Ad esempio su una macchina con 32 mb di ram totale il processo x alloca 20 mega di memoria, li libera con free() ma resta in esecuzione. Un nuovo processo y necessita di altri 20 mega, ma stando all'output del comando free non ci sono risorse sufficienti. Che succede in questo caso, le risorse bufferizzate vengono spazzate via o il kernel inizia ad usare lo swap ? Mi auguro la prima :lol:
Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch

Re: [C] free

Messaggioda Mario Vanoni » mar giu 03, 2008 14:03

Dani ha scritto:E cosa accade alla memoria bufferizzata qualora un nuovo processo desideri allocarne altra per se ?

Ad esempio su una macchina con 32 mb di ram totale il processo x alloca 20 mega di memoria, li libera con free() ma resta in esecuzione. Un nuovo processo y necessita di altri 20 mega, ma stando all'output del comando free non ci sono risorse sufficienti. Che succede in questo caso, le risorse bufferizzate vengono spazzate via o il kernel inizia ad usare lo swap ? Mi auguro la prima :lol:


Come detto, UNIX usa tutta la memoria disponibile.
Se allocata, poi liberata con free, rimane li`.
La ripetizione di un programma impiega meno tempo!
Se un altro processo richiede memoria, usera` quella liberata,
se non ne trova piu`, entrera` il famigerato OOM killer.

Esempio pratico, puoi usare il tuo programma per testare:

- cd /zz/src
- du -hs dice 19GB

- macchina (ab)usata, top dice 4GB used, 130M free
- time (built-in) o /usr/bin/time (con le opzioni -p -a -o /path/file) ls -alR > /dev/null
- la prima volta 1m5..., top 19MB free
- ripetuto dieci volte, ora sempre 0m5..., top sale a 39M free

- stessa macchina dopo reboot, top dice 180M used, 3.9GB free
- time (built-in) o /usr/bin/time (con le opzioni -p -a -o /path/file) ls -alR > /dev/null
- la prima volta 1m5..., top 590MB used, 3.5GB free
- ripetuto dieci volte, ora sempre 0m5..., top scende a 355M free
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: [C] free

Messaggioda robbybby » mar giu 03, 2008 21:09

Con il seguente programmino, usando top per controllare quanta memoria il tuo programma usa, vedi che malloc alloca la ram, e free la dealloca SUBITO, e non al termine del programma.
Se non metto il memset(), cioe' se non uso la memoria allocata con malloc() la memoria in realta' non viene occupata.

Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>

#define CNT 90000000

int main()
{
int *pi = 0;
int i = 0;

  puts("1\n");
  scanf("%i",
            &i);

  pi = malloc(CNT * sizeof(int));
  printf("Pointer: %x\n",
            pi);
  memset(pi,
                0,
               sizeof(int) * CNT);

  puts("2\n");
  scanf("%i",
            &i);

  free(pi);

  puts("3\n");
  scanf("%i",
            &i);

  return 0;
}
Avatar utente
robbybby
Linux 3.x
Linux 3.x
 
Messaggi: 1176
Iscritto il: sab dic 16, 2006 10:48
Località: Fra Trantor e Terminus
Slackware: 13.1 / 64 bit
Kernel: 3.3.x
Desktop: KDE 4.4.5


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti