2010-06-27 8 views
8

This question mi ha fatto incuriosire. Domande come questa ottengono sempre risposte come "È generalmente sicuro, ma non si deve presumere che il sistema operativo lo farà per te", il che suona come un buon consiglio per me, ma mi chiedo: ci sono stati sviluppati attivamente (rilasciati) sistemi operativi che non lo fanno?Quali sistemi operativi non liberano memoria all'uscita dal programma?

E 'questo qualcosa che è stato fissato indietro nell'era dei dinosauri (80)?

+0

Su Windows c'è un problema simile: i file temporanei. La maggior parte dei programmi che necessitano di memoria aggiuntiva per le loro operazioni (e vengono eseguiti su computer che potrebbero non avere memoria sufficiente) utilizzano file temporanei. Data la facilità con cui un programma si arresta in modo anomalo o viene interrotto dall'utente, i file temporanei non vengono puliti. – rwong

risposta

10

risposta è "nessuno". Anche un programma su DOS anni fa avrebbe rilasciato memoria al termine del programma (semplicemente dal fatto che nulla stava gestendo la memoria quando il programma si fermava). Sono sicuro che qualcuno potrebbe vedere che il codice della modalità kernel non necessariamente libera la sua memoria all'uscita dalla app o potrebbero citare qualche oscuro OS incorporato .... ma si può presumere che l'app-exit restituisca tutta la memoria acquisita dal codice in modalità utente . (Windows 3.x potrebbe avere questo problema a seconda di quale allocatore è stato utilizzato ...)

Il motivo per cui "è necessario liberare la memoria" è che per l'ingegneria del software su larga scala, è necessario sforzarsi di sviluppare componenti che sono flessibili nel loro uso perché non sai mai come qualcuno cambierà l'uso del tuo codice molto tempo dopo aver lasciato il team.

Pensa a questo. Supponiamo che tu abbia progettato alcune classi progettate per essere un singleton (solo una volta istanziata durante la durata dell'app). Come tale, decidi di non preoccuparti della pulizia della memoria quando il tuo componente si distrugge o viene finalizzato. Questa è una decisione perfetta per quel momento. Anni dopo, dopo che sei partito per un pascolo più verde, potrebbe venire qualcun altro e decidere di dover utilizzare la tua classe in più luoghi, in modo tale che molte istanze andranno e vengono durante la durata dell'app. La tua perdita di memoria diventerà il loro problema.

nella mia squadra, abbiamo spesso parlato di fare l'utente avviato "stretta" dell'applicazione essere solo exit() senza fare alcuna pulizia. Se lo faremo, farei in modo che il team sviluppi classi e componenti che si ripuliscono correttamente da soli.

+0

+1. Mi piace che tu abbia continuato affermando perché non ci sono scuse per perdite di memoria. – stinky472

+2

Anche se la memoria verrà ripulita dal sistema operativo, una chiamata diretta a 'exit()' può ancora causare perdite (e quindi non è appropriata come risposta a "close"). Ci sono risorse non di memoria che probabilmente non verranno ripulite dal sistema operativo (come i blocchi di file). – Mankarse

1

recenti del sistema operativo Unix-like non riesce a liberare tutta la memoria di processo quando un processo termina, in cui recente probabilmente significa "dal 1970 o giù di lì". Sono abbastanza sicuro che i vecchi sistemi operativi per PC come DOS e CP/M avevano questo problema e alcune versioni precedenti di Windows. Non ne so abbastanza del recente Windows per essere sicuro, ma sarei molto sorpreso se qualcuno di Windows XP, Vista o Windows 7 avesse problemi a liberare memoria di processo.

Come regola generale, suggerirei che qualsiasi sistema operativo che non utilizza la memoria virtuale per dare ai processi spazi di indirizzi separati è probabilmente vulnerabile alla perdita di memoria quando i processi falliscono in modi importanti. Una volta che un sistema operativo ha implementato spazi di indirizzi virtuali per processo, deve già tenere traccia di tutta la memoria fisica allocata ad un processo, quindi liberarlo in modo affidabile è semplice.

Detto questo, è spesso una buona idea per scrivere i programmi per pulire dopo loro stessi comunque. Tende a portare a sottocomponenti meglio progettati e rende anche più facile applicare strumenti che cercano perdite di memoria e simili.

+2

DOS non ha avuto questo problema, e dubito che CP/M abbia fatto entrambe le cose. L'uscita del programma riporta semplicemente il puntatore a dove allocare la memoria successiva, il che significa che qualsiasi memoria precedentemente allocata al programma verrà sovrascritta dal prossimo programma da eseguire. –

3

In CP/M, non era una questione di liberare la memoria così tanto, dal momento che aveva una zona statica di RAM per il programma, e ogni programma eseguito nello stesso spazio. Quindi, quando il programma A si interrompe e il programma B viene eseguito, B viene semplicemente caricato sopra A.

Ora c'erano dei meccanismi per riservare la memoria dal sistema operativo, ma in genere non si trattava di memoria heap (nel classico caso che consideriamo oggi), è stata la progettazione di aree riservate speciali per varie attività.

Ad esempio, DOS ha questa routine di uscita denominata "Terminate and Stay Resident". Questo "chiude" il programma, ma non ha rilasciato lo spazio dopo la chiusura del programma. In genere questi programmi caricavano i vettori di interrupt (come gli interrupt di tastiera) per attivare le routine. Borland Sidekick era un "TSR" molto popolare nel corso della giornata e offriva cose come una calcolatrice e una lista di contatti.

Infine, poiché questi non erano sistemi di memoria protetti, i vostri programmi potrebbero abusare del sistema in tutti i modi possibili per fare ciò che volete, ma questa è una discussione diversa.

+0

Per riferimento futuro dei lettori: DOS "exit" syscalls 'int 21h (ah = 4ch)', 'int 20h' e' int 21h (ah = 0) 'fanno memoria libera allocata da' int 21h (ah = 48h) ' , a differenza di "TSR" 'int 21h (ah = 31h)', che non lo fa. – Ruslan

Problemi correlati