2011-11-25 15 views
23

Molte librerie come SDL, ecc., Ecc. Nei loro tutorial, chiamano le risorse libere prima di uscire dal programma, ma per quanto ne so, la maggior parte dei sistemi operativi libera la memoria dai processi quando escono, perché devo disturbarmi liberarli se l'applicazione sta per uscire comunque?Perché risorse gratuite se il programma sta già uscendo?

+0

Forse, solo per rimanere coerenti? Una buona abitudine? – Nawaz

+0

Sebbene ci sia un valore a questa domanda, non penso che sia appropriato per SO, poiché può solo sfociare in una Guerra Santa se non è nel contesto di un caso d'uso specifico. –

risposta

19

Anche se il vostro sistema operativo (non tutti farlo) libera la memoria in uscita, ci sono alcune ragioni:

  • è bene maniera
  • si aggiunge la simmetria, quindi il codice sembra migliore
  • OS non lo fa libera automaticamente alcune risorse all'uscita, come dispositivi (sensori, scanner ...)
  • se qualcuno prende questo codice e lo inserisce in un programma che utilizza le librerie solo in una piccola parte del suo runtime, le risorse saranno libere quando non necessario.
  • se stai cercando perdite di memoria errate, il tuo debugger non troverà queste non importanti.
2

Queste sono buone maniere.

E non si sa mai se si desidera trasformare il programma in qualcosa che continua a ripetersi continuamente nel futuro.

Detto questo, non è obbligatorio e come sempre puoi infrangere le regole se sai cosa stai facendo.

3

Una ragione che vedo è:

Si supponga che le perdite di memoria in dumping nella finestra di output del vostro ambiente di sviluppo in uscita dell'applicazione. Se non "ripulisci" in modo corretto avrai problemi a rilevare le vere perdite da tutte le perdite che derivano da "non preoccuparti"

8

Se le risorse assegnate a un programma verranno recuperate o meno dipende dai sistemi operativi. Si noti che in particolare alcuni sistemi incorporati non liberano le risorse.

La maggior parte dei sistemi operativi recupera e libera le risorse assegnate, ma è una pratica sbagliata fare affidamento sul comportamento del sistema operativo per questo e quindi è necessario liberare tutte le risorse acquisite prima di uscire dal programma.

+4

Perché è una cattiva pratica affidarsi al comportamento del sistema operativo? Senza fare affidamento sul comportamento del sistema operativo, ad esempio, non è possibile leggere o scrivere dati. –

+0

@JamesKanze: per garantire che i programmi siano trasferibili su più piattaforme. –

+3

Ma poi, non hai intenzione di fare alcun output o input, neanche. L'output e l'input sono probabilmente meno portatili del conteggio sul sistema operativo per recuperare memoria. (In pratica, se ci si trova in un ambiente ospitato, il sistema operativo ripristinerà la memoria.In un ambiente indipendente non si può contare su di esso, ma in un ambiente indipendente non si può contare sul fatto che iostream sia presente .) –

23

La memoria e le risorse non sono la stessa cosa.

La memoria viene rilasciata automaticamente.

Le risorse possono essere o non essere rilasciate automaticamente.

+0

+1 per l'unica risposta corretta finora. –

+3

Potrebbe fornire esempi di ciò che non viene rilasciato automaticamente nei sistemi operativi moderni? –

+0

I GUEST bitmap di GUESS verranno rilasciati automaticamente e un handle per uno scanner POTREBBE non essere ... a seconda del driver del dispositivo. –

3

Bene è per lo più vero che oggi quasi tutti i sistemi operativi tradizionali effettivamente liberano tutte (o la maggior parte) risorse che un programma ha assegnato alla sua cessazione. Tuttavia, questo in primo luogo non è vero per tutte le risorse (ad esempio sui miei socket Mac aperti rimangono aperti per un po 'quando non sono chiusi correttamente al termine del programma) e in secondo luogo credo che non per tutti i sistemi operativi.

Storicamente, i sistemi operativi non hanno disturbato affatto (in particolare alcuni dei vecchi sistemi operativi a 16 bit), quindi la pulizia di tutte le risorse al termine della programmazione è diventata ed è ancora buona pratica di programmazione e un programmatore che non pulisce le sue cose è generalmente considerato un cattivo programmatore.

5

In generale sono d'accordo su ciò che altri hanno detto: se non pratichi buone abitudini nelle piccole cose, fallirai anche con quelle grandi. Comunque la tua domanda ha suonato (una vecchia) campana, sul software crash-only.

Mentre questo concetto si estende "un po '" oltre alla tua domanda iniziale (si tratta non solo con le risorse del sistema operativo, ma con solo (file aperti, ecc), si potrebbe ancora essere interessati a esso.

L'idea di base è che se il software non deve distruggere i dati dell'utente, ecc. Di fronte a un arresto anomalo (si pensi ai database/registri di tx, ecc.), Perché si dovrebbe progettare/programmare un percorso di uscita pulito. eseguire di nuovo esso, si potrebbe anche "Let it crash".

Beh, credo che si può discutere circa le virtù di quel tutto il giorno, ma è comunque interessante.

4

È una buona idea ripulire dopo te stesso.

Per uno: liberare risorse riordina i descrittori di file/connessioni di rete/memoria condivisa ecc. In modo controllato.

In secondo luogo, se si utilizza qualcosa come purity è possibile assicurarsi che tutta la memoria sia presa in considerazione, dando così una migliore sensazione che non si verifichino perdite di memoria.

3

Prima di tutto: non tutte le risorse vengono liberate dal sistema operativo quando processo si conclude, ad esempio:

  1. Files - a volte si può cosa rimuovere i file che si aveva aperto.
  2. Risorse denominate: mutex denominate, memoria condivisa, ecc. Ecc.
  3. Più complessi livelli di stato dell'applicazione, statistiche e molto altro.

Quindi, una volta gestite tutte le risorse nello stesso modo in cui si sta facendo la cosa giusta.

+2

Almeno in Windows, tutti gli handle degli oggetti del kernel (ovvero i file, i mutex denominati e così via) vengono chiusi all'arresto del processo. –

+2

Almeno in Linux, tutti i descrittori di file (ovvero file, mutex denominati, ecc.) Vengono chiusi quando il processo viene rimosso dalla tabella del processo. –

+0

Sto parlando di cose come i mutex denominati - non vengono disattivati ​​automaticamente o la memoria condivisa SYSV e l'IPC in generale sono persistenti. mq_ code persistenti e altro ancora. Naturalmente ci possono essere file temporanei dell'applicazione, ad esempio il journal sqlite3 e altro. Quindi ci sono molte risorse non tutte ripulite dal sistema operativo – Artyom

3

Sei corretto, i sistemi operativi più moderni rilasceranno memoria, handle di file, ecc. Al momento della chiusura dell'applicazione. Quindi sarei pienamente d'accordo con te e non mi preoccuperei di liberare risorse se le risorse disponibili per le applicazioni erano illimitate.

Il fatto è che le risorse non sono illimitate, in realtà è esattamente l'opposto, quindi tutto ciò che si prende è qualcosa che un'altra applicazione in esecuzione sul sistema non può avere. In molti casi avrai bisogno di una risorsa non per tutta la vita della tua app, ma solo per una parte di essa, quindi vuoi divertirti con il resto del sistema e prendere solo ciò di cui hai bisogno mentre ne hai bisogno.

La pratica di non rilasciare risorse è molto comune nei dispositivi incorporati, poiché per questi l'applicazione è l'unica cosa in esecuzione e non riesce nemmeno ad uscire, l'unica via d'uscita è quella di spegnere il dispositivo. Io lavoro con uno di questi sistemi, e mentre il dispositivo embedded non ha problemi di non rilasciare roba, noi ingegneri soffrire per diversi motivi:

  • durante il test l'applicazione incorporato in un normale PC siamo costretti a modellare la dispositivo simulato come processo che inizia e finisce. Se le risorse sono state rilasciate correttamente, è possibile che un singolo processo esegua diversi test nella stessa esecuzione, inclusi i test che avviano e arrestano il dispositivo simulato.
  • a un certo punto abbiamo dovuto lavorare su un progetto che ci richiedeva di prendere parte al codice incorporato e pubblicarlo come libreria di collegamento dinamico per Windows/Linux che esegue un sottoinsieme delle funzioni del dispositivo reale, ma senza il dispositivo reale. A causa del problema delle risorse, gli utenti non possono caricare e scaricare questa DLL più volte nelle loro applicazioni, perché ogni volta che fanno ciò viene preso un bel po 'di memoria e non viene mai rilasciato. L'abbiamo documentato come una limitazione, chiediamo ai nostri utenti di collegare la libreria all'applicazione anziché caricarla dinamicamente. Sfortunatamente dopo oltre 10 anni che questo dispositivo embedded è stato in fase di sviluppo, sarebbe molto complicato individuare e correggere tutte queste allocazioni di risorse, quindi continuiamo a rimandare e ad avere invece un prodotto non ottimale.
  • quando utilizziamo strumenti di analisi del codice statici e dinamici per individuare i difetti reali otteniamo un sacco di falsi positivi, così tanti che abbiamo dovuto sviluppare strumenti che filtrassero quelli per non rischiare di perdere quelli reali in tutto il rumore.

Il mio consiglio è di scrivere il codice come se il sistema operativo non ti fosse d'aiuto, poiché questo è ciò che ti darà più possibilità di migliorare il software in futuro.

4

Suppongo che la prima cosa da menzionare sia che non tutte le risorse sono uguali.

Nessuna di queste strutture (nella maggior parte dei sistemi operativi) vengono puliti automaticamente alla chiusura dell'applicazione:

  • pool di memoria condivisi
  • Chiamato Win32 Mutex/Semaforo/eventi/etc. oggetti
  • Alcuni tipi di connessioni socket
  • proprietari delle strutture dati driver di periferica hardware (oscuri)

... e sono sicuro che mi sto dimenticando alcuni.

Nel piccolo, potrebbe essere facile sapere se l'applicazione utilizza uno di questi tipi di oggetti e il controllo per esso. Tuttavia, nelle applicazioni più grandi non è difficile arrivare a un punto in cui si dispone di un sottosistema profondamente integrato (di terze parti?) Che assegna una o più di queste strutture speciali e se il resto dell'applicazione perde come un setaccio, potresti essere nei guai.

È davvero una questione di disciplina ingegneristica che dice che l'applicazione dovrebbe ripulire se stessa in uscita. Potresti non averne bisogno ora, ma potresti apprezzarlo in seguito, man mano che la tua applicazione si ingrandisce.

0

Non è necessario liberare memoria quando l'applicazione si chiude. Il sistema operativo si occupa di recuperare la memoria. Come altri hanno menzionato, risorse come stampante, file richiedono di liberare i blocchi per consentire ad altri programmi di accedervi.

Se il proprio codice non libera memoria (anche quando viene eseguito) e quando le dimensioni del codice/progetto aumentano, si mangerà tutta la memoria del sistema e la manutenzione diventa difficile risolverli. Quindi, per tutti gli scopi futuri, è una buona pratica liberare memoria.

0

Come sapete, a seconda del sistema operativo, la memoria è di solito (si spera sia!) Rilasciare automaticamente quando il processo si interrompe.

Tuttavia, molte biblioteche, come SDL, chiedere al sistema operativo di allocare le risorse di sistema che non si ottiene liberato in un fasion tempestivo (forse nemmeno di arresto fino a) se non esplicitamente liberato dall'applicazione.

Oltre ad essere bello per il sistema operativo e per la sua pulizia, liberare tutta la memoria allocata è importante in qualsiasi applicazione che viene eseguita per un periodo di tempo sconosciuto perché quella memoria occupa spazio che altre applicazioni potrebbero aver bisogno.

È anche una buona abitudine ripulire dopo te stesso. :)

0

Come evidenziano le altre risposte, c'è una differenza tra risorse e memoria. Posso parlare solo nel contesto dell'API Win32, ma sono sicuro che concetti simili sono applicabili a librerie come SDL. Alcune librerie possono prevedere il rilascio automatico delle risorse, altre no. È sempre buona pratica liberare le risorse in modo irregolare. Le risorse specifiche del dispositivo sono un esempio di risorse che potrebbero causare problemi se non vengono liberate. Potresti voler verificare con la documentazione della tua biblioteca i dettagli sulla gestione delle risorse.

2

Il sistema operativo cerca di liberare tutte le risorse ancora detenute da un processo dopo si chiude come un ultimo disperato tentativo per mantenere il sistema in esecuzione. Le applicazioni devono ripulire se stesse, ma l'auto-pulizia del sistema operativo è progettata per e interrompe i programmi scritti male che rimuovono l'intero sistema da perdite di memoria, file archiviati, ecc. Quindi non dovresti fare affidamento su di esso come modalità predefinita per la tua applicazione deve essere chiusa! Idealmente, il sistema operativo non dovrà mai essere ripulito dopo che un processo è stato chiuso, poiché tutti i programmi dovrebbero essere ben scritti per ripulire se stessi. Tuttavia, in pratica, alcuni software hanno errori o sono semplicemente scritti male ed è una funzione utile per il sistema operativo per ripulire dopo questi programmi pigri.

Inoltre, il sistema operativo non pulirà comunque alcune risorse. Se si scrive un file su disco e si intende rimuoverlo allo spegnimento, il sistema operativo non cancellerà automaticamente quel file (e se fosse il documento dell'utente?). Ma se non lo ripulisci da solo, il tuo programma ha permanentemente "perso" spazio su disco. Ci sono molti altri altri esempi per altri tipi di risorse diversi dai file.

Quindi non scrivere software non valido che presuppone che il sistema operativo si ripulisca: probabilmente non lo farà al 100% e tale meccanismo è solo per software scadente. Scrivi invece un buon software!

-1

Ogni volta che inizia un nuovo processo, ad esso viene assegnata una memoria. La memoria può essere di quattro tipi come:

1.Heap 
2.Local 
3.Virtual 
4.Global 

locale generalmente utilizzato per gli indirizzi del main() di variabili perché queste variabili principali saranno utilizzati di frequente. Global mantiene il registro delle variabili globali. La memoria heap viene allocata (le pagine sono assegnate) ai programmi o ai processi e contiene le informazioni sui dati e sulle funzioni del programma.

Che cosa effettivamente accade che OS utilizza il concetto di puntatori. E ogni volta che nel programma un puntatore inizia a puntare su un'altra memoria (a causa di un errore di codice) e smette di puntare alla posizione di memoria precedente, l'ultimo spazio di memoria è ancora in uso nella memoria heap. ma questo spazio di memoria non serve a niente. Quando un programma esce, rilascia la memoria in base alla sua posizione di variabili e funzioni. Ma come ho detto alla memoria non appuntita hanno ancora dati ma nessuno lo sta indicando in modo che il programma non possa rilasciarlo.

Per rilasciare quella posizione di memoria non utilizzata viene utilizzato free(). Come malloc, realloc, calloc, free all sono le funzioni della memoria heap. Quando chiamiamo libero cancella le pagine che sono state assegnate per il programma e rilascia anche quella memoria inutilizzata.

In simple words, 

50-100 posizione di memoria assegnata al programma. aeb (variabili nel programma) puntano a 60 e 70. a causa di un errore di codice, b inizia puntando a 60. Quindi ora a e b puntano entrambi a 60. Nessuno punta a 70 ora. Quando il programma comincerà ad uscire, otterrà la locazione di memoria di ae la rilascerà. Quindi otterrà la posizione di memoria di b e la rilascerà. Ma il programma non verrà mai a sapere la posizione di 70 perché nessuno lo sta puntando. non rilasciare la memoria di 70.

Considerando che quando si chiama free() rilascia direttamente l'intera pagina e con quella posizione di memoria 50-100 sarà rilasciata. Ora entrambe le posizioni di memoria non appuntite e appuntite sono gratuite per l'uso.

Ora un giorno le lingue dispongono di garbage collector per svolgere la funzione di free(). Ma se parliamo dei sistemi operativi, devono farlo da soli, quindi nelle biblioteche viene sempre utilizzato gratuitamente. Ed è anche il miglior modo di scrivere codice.

1

Il senso di rilasciare la memoria anche per oggetti la cui durata corrisponde a quella di un'applicazione è immediatamente evidente una volta che si tenta di trovare una perdita di memoria con Valgrind o qualcosa del genere, perché l'output sarà inondato di report su tali oggetti. Dopo tutto, una perdita è ancora una perdita.

0

So che sono in ritardo per la festa, ma per favore liberate tutta la vostra memoria e risorse, se non altro perché quando finite per avere una vera perdita di memoria, come in un loop, quindi l'ultima cosa che ho è necessario che la tua spazzatura ingombra i miei profiler di memoria in uscita come valgrind.

In secondo luogo, la pulizia della memoria non è un problema Utilizzare indicatori intelligenti per eseguire tutto il lavoro con poco o nessun sovraccarico.

Infine, questo è ancora più imperdonabile se si tratta di una libreria, non mi interessa se non si tratta di una perdita continua (ad esempio 1 spazzatura off - ad esempio: creazione di un singleton) una libreria non deve lasciare i dati sul freestore .

Problemi correlati