2014-04-15 16 views
5

state avendo questa discussione con un collega. quando linguaggi come C# o java garbage raccolgono oggetti come stringhe, restituendoli all'heap, puliscono anche questo blocco di memoria, ad esempio sovrascrivendo con 0 o 1?La memoria è stata cancellata prima della garbage collection?

la mia ipotesi è che il blocco viene restituito così com'è, a meno che non si utilizzino classi come securestring con finalize overload, a 0 out del blocco.

+0

sarebbe * logic *, almeno per me, per azzeramento, per motivi di sicurezza. – Eugene

+0

Correlati: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794 – Servy

+1

Di solito le implementazioni linguistiche favoriscono le prestazioni. Quindi, azzerano solo la memoria quando devono, e data la scelta di farlo quando si raccolgono i rifiuti * o * quando si assegnano, scelgono quando allocare - semplicemente perché seguono il principio "fai il minimo lavoro possibile". – Durandal

risposta

3

In pratica, no, questo non accade. La sovrascrittura della memoria che hai appena liberato richiede tempo, quindi ci sono delle penalizzazioni in termini di prestazioni. Gli oggetti "protetti" come SecureString sono just wiping themselves, non fanno affidamento sul GC.

Più in generale, dipende molto da quella particolare implementazione di quel particolare linguaggio. Ogni linguaggio che presuppone l'esistenza di un GC (come C#) specifica regole diverse su come e quando deve avvenire la garbage collection.

di prendere il vostro C# esempio, le specifiche C# non richiede che gli oggetti vengono sovrascritti dopo essere stato liberato, e non vieta neanche:

Infine, a un certo momento dopo che l'oggetto diventa idoneo per raccolta, il garbage collector libera la memoria associata a quell'oggetto.

§3.9 C# 5.0 Language Specification

Se la memoria viene poi assegnato a un tipo di riferimento, avrete un costruttore che fa il proprio inizializzazione personalizzato. Se la memoria viene successivamente assegnato a un tipo di valore, esso viene azzerato prima di poter iniziare la lettura da esso:

inizializzazione a viene in genere fatto da avere il gestore di memoria o garbage collector valori di default inizializzare la memoria a tutti i bit -zero prima che venga assegnato per l'uso. Per questo motivo, è conveniente utilizzare all-bit-zero per rappresentare il riferimento null.

§5.2 C# 5.0 Language Specification

Inoltre, ci sono almeno due implementazioni di C# - implementazione di Microsoft e l'implementazione di Mono, quindi basta dicendo "C#" non è abbastanza specifico. Ogni implementazione potrebbe decidere di sovrascrivere la memoria (o meno).

+0

probabilmente una domanda stupida, ma cosa succede se hai liberato due byte A e B, e B ne ha alcuni (alcune informazioni). GC recupera la memoria e questi due byte vengono assegnati a qualcun altro, che scrive solo in un byte. Come sarà gestito? Questo non induce dati obsoleti? – Eugene

+0

@Eugene: Supponendo che fosse possibile in un linguaggio ipotetico, questo sarebbe generalmente considerato un errore di programmazione. È sempre necessario inizializzare i dati prima di leggerli. –

+0

@Eugene Al di fuori del codice 'non sicuro ', in C# non è * possibile leggere la memoria che non è stata allocata per te. Si fa in quattro per assicurarsi che * non sia in alcun modo * leggere la memoria dopo che è stata liberata. Se la memoria è assegnata a un codice non scritto in C# e decide di leggere la memoria allocata per esso senza prima averlo cancellato/impostato, può farlo. Non esiste un comportamento definito per ciò che vedrà in questi casi. – Servy

2

Per quanto ne sappia, non c'è un singolo garbage collector che in realtà cancella la memoria con 0 o nessun numero. Garbage collector C# e Java reclamare la memoria da oggetti non utilizzati e contrassegnarla come disponibile. SecureString si asciuga alla finalizzazione ma non è una cosa da GC.