2010-11-10 3 views
27

Quando diciamo un programma perdite di memoria, diciamo un nuova senza eliminare in C++, lo fa davvero perdite? Voglio dire, quando il programma finisce, quella memoria è ancora assegnata ad un programma non in esecuzione e non può essere usata, o il sistema operativo sa quale memoria è stata richiesta da ciascun programma e la rilascia quando termina il programma? Se eseguo quel programma un sacco di volte, esaurirò la memoria?Una perdita di memoria dell'applicazione causa una perdita di memoria del sistema operativo?

+0

possibile duplicato di [Perdita di memoria in C, C++; ho dimenticato di fare gratuitamente, cancellare] (http://stackoverflow.com/questions/1232262/memory-leak-in-cc-forgot-to-do-free-delete) – nmichaels

+0

Sto imparando C++, e ho paura che ogni volta eseguo il mio programma, sto usando più memoria (sto ancora lavorando alle mie capacità di gestione della memoria) – baruch

+0

Anche di http://stackoverflow.com/questions/104/anatomy-of-a-memory-leak –

risposta

19

Su sistemi operativi con memoria protetta (Mac OS 10+, tutti i cloni Unix come Linux e sistemi Windows basati su NT che indicano Windows 2000 e versioni precedenti), la memoria viene rilasciata al termine del programma.

Se si esegue un programma abbastanza spesso senza chiuderlo (eseguendo sempre più istanze contemporaneamente), si esaurirà la memoria, indipendentemente dal fatto che vi sia o meno una perdita di memoria, quindi è anche vero per i programmi con perdite di memoria. Ovviamente, i programmi che perdono memoria riempiono la memoria più velocemente di un programma identico senza perdite di memoria, ma quante volte è possibile eseguirlo senza riempire la memoria dipende molto piuttosto dalla quantità di memoria necessaria per il normale funzionamento del programma rispetto alla presenza di una perdita di memoria o non. Quel confronto non vale davvero nulla a meno che non si stiano confrontando due programmi completamente identici, uno con una perdita di memoria e uno senza.

Le perdite di memoria diventano le più gravi quando si esegue un programma per un tempo molto lungo. Esempi classici di questo sono i software server, come i server web. Con giochi o programmi di fogli di calcolo o word processor, ad esempio, le perdite di memoria non sono così gravi perché alla fine si chiudono quei programmi, liberando la memoria. Ma naturalmente le fughe di memoria sono piccole bestie cattive che dovrebbero essere sempre affrontate come una questione di principio.

Ma come detto in precedenza, tutti i sistemi operativi moderni rilasciano la memoria quando il programma si chiude, quindi anche con una perdita di memoria, non si riempie la memoria se si sta aprendo e chiudendo continuamente il programma.

+0

Curioso: perché tutti i programmi perdono memoria?Stai dicendo che questa è una caratteristica fondamentale dell'architettura di von Neumann, o che tutti i programmi hanno inevitabilmente errori di codifica? –

+2

Penso che il punto sia che tutti i programmi * usano * la memoria, un po 'più efficientemente di altri. Alcuni programmi che tecnicamente non perdono usano ancora la memoria in modo molto inefficiente (tenendola allocata per molto più tempo del necessario, anche se alla fine è stata rilasciata). –

+0

Nessun programma esaurirà la memoria. Pensa a un kernel del sistema operativo che funziona senza sosta per anni: è anche un programma. – orip

3

Al termine del processo, anche la memoria viene cancellata. Il problema è che se un programma perde memoria, richiederà sempre più OS del sistema operativo e potrebbe causare il crash del sistema operativo.

14

La memoria con perdite viene restituita dall'OS dopo l'esecuzione dell'esecuzione.

Ecco perché non è sempre un grosso problema con le applicazioni desktop, ma è un grosso problema con server e servizi (tendono a funzionare a lungo.).

consente di guardare il seguente scenario:

  1. Programma A chiedere la memoria dal sistema operativo
  2. Il sistema operativo segna il blocco X come stato utilizzato da A e lo restituisce al programma.
  3. Il programma deve avere un puntatore a X.
  4. Il programma restituisce la memoria.
  5. Il sistema operativo contrassegna il blocco come libero. L'utilizzo del blocco ora provoca una violazione di accesso.
  6. Il programma A termina e tutta la memoria utilizzata da A è contrassegnata come non utilizzata.

Niente di male.

Ma se la memoria viene allocata in un ciclo e l'eliminazione è dimenticato, si esegue in problemi reali:

  1. Programma A chiedere la memoria dal sistema operativo
  2. Il sistema operativo segna il blocco X come state utilizzate da A e lo restituisce al programma.
  3. Il programma dovrebbe avere un puntatore a X.
  4. Goto 1

Se il sistema operativo esaurisce la memoria, il programma probabilmente andrà in crash.

5

No. Una volta che il sistema operativo termina la chiusura del programma, la memoria ritorna (con un sistema operativo ragionevolmente moderno). Il problema è con i processi di lunga durata.

3

È più una perdita, nel senso che il codice stesso non ha più presa sul pezzo di memoria.

36

No, in tutti i pratici sistemi operativi, quando un programma termina, tutte le sue risorse vengono recuperate dal sistema operativo. Le perdite di memoria diventano un problema più serio nei programmi che potrebbero continuare a funzionare per un periodo di tempo prolungato e/o funzioni che possono essere chiamate spesso dallo stesso programma.

+0

' tutte le sue risorse '- non è vero per alcuni oggetti persistenti, allocati dal sistema operativo per processo, come i descrittori SysV IPC (ci sono anche alcuni oggetti shm) e alcuni gestori di vedove. – osgx

+0

Quindi è meglio sempre eliminare/liberare quando c'è un nuovo/malloc? – jokoon

2

Il sistema operativo può rilasciare la memoria al termine del programma. Se una perdita esiste in un programma, allora è solo un problema mentre il programma è in esecuzione. Questo è un problema per programmi di lunga durata come i processi del server.Oppure, ad esempio, se il tuo browser web avesse una perdita di memoria e lo avessi mantenuto in funzione per giorni, avrebbe gradualmente consumato più memoria.

2

Per quanto ne so, sulla maggior parte del sistema operativo all'avvio di un programma riceve un segmento di memoria definito che verrà completamente liberato una volta terminato il programma.

Le perdite di memoria sono uno dei motivi principali per cui sono stati inventati algoritmi di garbage collector poiché, una volta inseriti nel runtime, diventano responsabili nel recuperare la memoria che non è più accessibile da un programma.

1

Le perdite di memoria non persistono oltre la fine dell'esecuzione, quindi una "soluzione" a qualsiasi perdita di memoria è semplicemente terminare l'esecuzione del programma. Ovviamente questo è più di un problema su alcuni tipi di software. Avere un server di database che deve andare offline ogni 8 ore a causa di perdite di memoria è più un problema di un videogioco che deve essere riavviato dopo 8 ore di gioco continuo.

Il termine "perdita" si riferisce al fatto che nel tempo il consumo di memoria aumenterà senza alcun beneficio maggiore. La memoria "trapelata" non è memoria né utilizzata dal programma né utilizzabile dal sistema operativo (e da altri programmi).

Purtroppo le perdite di memoria sono molto comuni nel codice non gestito. Ho avuto Firefox in esecuzione per un paio di giorni e l'utilizzo della memoria è 424 MB, nonostante abbia solo 4 schede aperte. Se avessi chiuso firefox e riaperto le stesse schede, l'utilizzo della memoria sarebbe probabilmente pari a < 100 MB. Quindi 300+ MB ha "perso".

+2

L'esempio di Firefox non è necessariamente una perdita. I programmi possono mantenere una memoria allocata in precedenza in un "pool" e riutilizzarla invece di rilasciare e riallocare ogni volta che è necessario. È solo una "perdita" se il programma non contiene più un riferimento ad esso, rendendolo così irraggiungibile. – baruch