2012-01-19 16 views
6

Ciao a tutti quando si scrive un'implementazione di una lista di array, capisco che è importante impostare Item(x) su null quando viene rimosso (invece di semplicemente quantity -= 1) in modo da evitare perdite di memoria.Le matrici di primitive "non zero" richiedono più memoria?

Tuttavia, se il mio elenco di array è un primitivo elenco di array int (supportato da un int[]), ha senso impostarlo su 0?

Analogamente, per un elenco di caratteri primitivi (supportato da un char[]), quando viene chiamato RemoveRange(), ha senso riempire tale intervallo con \u0000? O è del tutto normale aggiornare semplicemente il length e i puntatori senza modificare l'array di supporto?

è un array di int riempiti con zeri eventualmente meno memoria occupante di un array di lunghezza pari riempito con valori interi perché il runtime potrebbe rendere ottimizzazioni?

+0

Se ricordo male, la risposta a questa è un po 'illogica. Lascerò a qualcuno più intelligente di fare la spiegazione solo perché la mia memoria è troppo confusa sull'argomento. – Esko

+0

È molto allettante confermare falsamente che un int [] diventa il più grande dei numeri più grandi che uno tiene. Alcune persone non hanno alcun modello di come funziona un computer? – Ingo

+0

@Ingo Stavo pensando che potrebbero essere fatte ottimizzazioni se avessero tutti lo stesso valore (cioè 0) – Pacerier

risposta

7

Un array di interi pieni di zeri occupa probabilmente meno memoria di un array di lunghezza uguale pieno di valori interi?

Supponendo che in entrambi i casi si tratti di uno int[] - no. Due array dello stesso tipo e della stessa lunghezza occuperanno sempre la stessa quantità di memoria.

Non c'è bisogno per sovrascrivere i vostri elementi dell'array "ora vuoti" con 0. Non sarebbe fare alcun danno (al di là di un miglioramento delle prestazioni molto piccolo), e può anche rendere più semplice le cose quando il debug, ma non lo fanno bisogno di.

1

No, non è necessario farlo con i tipi primitivi (vale a dire impostarli su 0) poiché l'unica ragione per cui gli "slot" sono annullati in modo esplicito sono per impedire riferimenti falsi ad essi avvitandoli con la garbage collection.

1

Non è possibile avere un ArrayList<int> né alcuna altra classe contenitore con primitive. Per quanto riguarda gli array semplici, vedi la risposta di Jon Skeets.

+1

Sono sicuro che lo sa e vuole creare la sua propria classe 'ArrayList' come' IntArrayList'. –

+0

+ Sanjay - Non ne sono così sicuro. Ad ogni modo, non dovrei rispondere a quello che qualcuno potrebbe aver voluto dire, ma a rispondere a quello che ha chiesto. – Ingo

+1

L'ho letto mentre sta implementando la propria lista di array (non usando ArrayList). – wmorrison365

1

Primitive e riferimenti occupano sempre la stessa quantità di spazio.

2

... quando si scrive un'implementazione lista di array, comprendo è importante impostare Item(x) a null quando viene rimosso (invece di quantity -= 1) in modo da evitare perdite di memoria.

Questo non è vero. Impostare le variabili su null non è qualcosa che è sempre necessario e non farlo non significa che si abbia una perdita di memoria.

Tuttavia, se la mia lista di array è una lista di array int primitiva, ha senso impostarla su 0?

No, per le primitive che non importa affatto, 0 o \u0000 (per un char) è solo un valore come qualsiasi altro valore. Non occupa meno spazio.

+1

È * necessario * se stai implementando un tipo 'ArrayList' come se. Se aggiungo un elemento e poi rimuovo quell'elemento dall'elenco, non voglio che quel riferimento sia in agguato nella lista senza motivo. –

+0

Se gestisci la tua memoria, devi gestire l'annullamento degli oggetti non utilizzati. In caso contrario, il GC lo preleva se non ci sono ulteriori riferimenti a quell'oggetto (in un tempo non specificato). – wmorrison365

+1

@JonSkeet Sì, probabilmente è una buona idea implementare il proprio 'Elenco'. Molte persone pensano però che impostare le variabili su "null" in generale sia una buona idea (senza capire esattamente perché). Secondo me, non dovresti fare le cose solo perché hai una vaga idea che sia "buono" - fallo solo se capisci perché. – Jesper

1

No, è necessario annullare lo slot dell'oggetto nell'array per impedire la perdita. Se l'oggetto è ancora referenziato dal tuo array, allora non può essere GC - quindi la perdita a cui fai riferimento.

I primitivi invece sono allocati nello stack in ogni caso, non nell'heap, quindi non sono comunque GC. I primitivi che sono classi di classi di istanze vengono memorizzati come campi dell'oggetto pertinente e ripuliti quando l'oggetto è in GC.

Inoltre, il JLS indica che le dimensioni di una primitiva sono specifiche della VM ma la maggior parte (tutte?) VM attualmente supporta 4byte int. Vedere lo JLS per maggiori informazioni:

Problemi correlati