2014-10-24 18 views
11

Ho una situazione in cui incontrerò molte stringhe duplicate che rimarranno nella memoria per un lungo periodo di tempo. Voglio usare String.Intern ma non voglio invadere alcuna potenziale risorsa applicativa dal momento che il mio progetto è una libreria. Come funziona?.NET crea un pool interno di stringhe per ogni assembly?

+2

Meh, internati stringhe di riferimento sono contati. L'oggetto principale che contiene un riferimento è una tabella (simile a HashSet) di proprietà di un AppDomain. Lo scaricamento dell'appodominio svuota la tabella, diminuendo il conteggio dei riferimenti. La stragrande maggioranza, se non tutte, le stringhe dovrebbero scomparire. Non c'è pericolo di "invasione". –

+0

Un po 'fuori tema ma durante la ricerca di varie informazioni sull'internamento delle stringhe ho trovato questo articolo del blog molto interessante: https://blog.benoitblanchon.fr/modify-intern-pool/. Vedi anche il codice sorgente associato. – AFract

risposta

11

La tabella stagista per le stringhe è CLR-scoped:

In primo luogo, la memoria allocata per oggetti String internati non è probabile scatta solo se il Common Language Runtime (CLR) termina. Il motivo è che il riferimento CLR dell'oggetto String internato può rimanere dopo che l'applicazione, o anche il dominio dell'applicazione, termina.

Quindi non solo la tabella interna non è specifica per l'assemblaggio, ma può sopravvivere al vostro assemblaggio. La buona notizia è che le stringhe duplicate non saranno un problema poiché le stesse stringhe letterali esistono con lo stesso riferimento una volta internate. Quindi si raccomanda Intern ing:

Il Common Language Runtime conserva stoccaggio stringa mantenendo un tavolo , denominata pool interno, che contiene un solo riferimento alle ogni stringa letterale unica dichiarata o creata a livello di codice in vostro programma. Di conseguenza, un'istanza di una stringa letterale con un valore particolare esiste solo una volta nel sistema.

string s1 = "MyTest"; 
string s2 = new StringBuilder().Append("My").Append("Test").ToString(); 
string s3 = String.Intern(s2); 
Console.WriteLine((Object)s2==(Object)s1); // Different references. 
Console.WriteLine((Object)s3==(Object)s1); // The same reference.