Sono immutabili anche gli interi raccolti dal Garbage Collector, come stringhe immutabili?

1

Ho già avuto l'idea che le variabili stringa siano immutabili, quindi vengono copiate in un altro punto nell'heap ogni volta che apportiamo una modifica e, poiché GarbageCollector deve raccoglierle continuamente, causano problemi di prestazioni.

La domanda è:

  • Anche i numeri interi o i doppi sono immutabili. Vengono copiati anche ogni volta che apportiamo una modifica?
  • In caso affermativo, tutte le copie sono raccolte dal garbage collector?
  • Nessuno si lamenta delle prestazioni relative al continuo cambiamento degli interi, mai. È perché non ha senso perché la memoria allocata deve essere sempre la stessa (8 bit, 16 bit, ecc.), A differenza delle stringhe?
posta Necati Hakan Erdogan 31.03.2017 - 12:58
fonte

1 risposta

3

Sebbene sia le stringhe che gli interi siano immutabili, non sono la stessa cosa. Le stringhe sono tipi di riferimento immutabili; gli interi sono tipi di valori immutabili.

Se si dispone di una variabile stringa, s , allora mantiene semplicemente un riferimento (un puntatore) alla posizione nell'heap in cui è archiviato quell'oggetto stringa. Se cambi la stringa a cui fa riferimento s , allora potenzialmente un nuovo oggetto stringa viene creato sull'heap e quello originale è idoneo per la garbage collection se non ci sono altri riferimenti a esso.

Se tuttavia hai una variabile int , i , allora contiene il valore intero. Se cambi il numero detenuto da i , allora quel valore cambia. Non c'è nessuna nuova allocazione dell'heap.

Certamente non è il caso che se si modificano le stringhe "il GarbageCollector deve raccoglierle tutto il tempo". Il garbage collector viene eseguito solo quando è necessario; è abbastanza probabile che durante la vita della tua app, non funzionerà mai. E anche quando viene eseguito, può essere molto veloce e non causare problemi di prestazioni. Non sto dicendo che non abbia mai problemi di prestazioni; ma sto dicendo che cambiare continuamente le stringhe non garantisce i problemi di prestazioni.

Modifica

Riguardo a StringBuilder , questo è un problema di copia della memoria; non una raccolta di rifiuti. A titolo di esempio, prendere in considerazione il seguente codice:

var strings = GetListOf1000StringsEach100CharactersLong();
var finalString = "";
foreach (var item in strings)
{
    finalString += item;
}

Che cosa succede quando corri quello è:

  • La prima volta, i 100 caratteri nelle stringhe [0] vengono copiati in una nuova posizione, a cui fa riferimento finalString .
  • La seconda volta attraverso il ciclo, quei 100 caratteri in finalString , più il 100 in strings[1] vengono copiati in una nuova posizione e finalString aggiornati in quel punto.
  • La terza volta, quei 200 caratteri in finalString , più il 100 in strings[2] vengono copiati in una nuova posizione e finalString aggiornati in quel punto ...
  • Nell'ultimo passaggio, quei 99900 caratteri in finalString , più il 100 in strings[999] vengono copiati in una nuova posizione e finalString aggiornati in quel punto!

Mentre scorre, il numero di caratteri che deve essere copiato aumenta e questi stessi caratteri vengono copiati più e più volte. Questo è un enorme problema di prestazioni. StringBuilder lo risolve semplicemente memorizzando i riferimenti alle stringhe originali e facendo solo quella copia una volta, quando viene chiamato ToString() . Questo dà una grande spinta alle prestazioni. Ma non è correlato alla garbage collection.

    
risposta data 31.03.2017 - 13:26
fonte

Leggi altre domande sui tag