2010-06-28 12 views
40

Eventuali duplicati:
Weird Java Boxinginteri caching in Java

Recentemente ho visto una presentazione in cui è stato il seguente esempio di codice Java:

Integer a = 1000, b = 1000; 
System.out.println(a == b); // false 
Integer c = 100, d = 100; 
System.out.println(c == d); // true 

Ora sono un poco confuso. Capisco perché nel primo caso il risultato è "falso" - è perché Integer è un tipo di riferimento e i riferimenti di "a" e "b" sono diversi.

Ma perché nel secondo caso il risultato è "vero"?

Ho sentito un'opinione, che JVM memorizza nella cache oggetti per valori int da -128 a 127 per alcuni scopi di ottimizzazione. In questo modo, i riferimenti di "c" e "d" sono gli stessi.

Qualcuno può darmi ulteriori informazioni su questo comportamento? Voglio capire gli scopi di questa ottimizzazione. In quali casi viene aumentata la prestazione, ecc. Il riferimento ad alcune ricerche su questo problema sarà grande.

+2

Si noti che non è possibile scrivere codice che dipende da questo comportamento poiché altri implementatori JVM/JDK non devono implementare questa ottimizzazione o, se lo desiderano, possono estendere l'intervallo dei valori memorizzati nella cache. – Behrang

+2

Si noti che la memorizzazione nella cache non si applica agli oggetti creati in modo esplicito. I.e. 'Intero a = 1; Integer b = new Integer (1); System.out.println (a == b); // prints false' – ccpizza

risposta

47

Voglio comprendere gli scopi di questa ottimizzazione . In quali casi viene aumentata la prestazione , ecc. Il riferimento ad alcune ricerche su questo problema sarà eccezionale.

Lo scopo è principalmente quello di risparmiare memoria, che porta anche a un codice più veloce grazie alla migliore efficienza della cache.

Fondamentalmente, la classe Integer mantiene una cache di Integer istanze nell'intervallo da -128 a 127, e tutti autoboxing, letterali ed usi di Integer.valueOf() restituirà istanze da quella cache per la gamma copre.

Si basa sul presupposto che questi piccoli valori si verificano molto più spesso di altri inte e quindi ha senso evitare il sovraccarico di avere oggetti diversi per ogni istanza (un oggetto Integer occupa qualcosa come 12 byte).

+8

Si noti che la cache funziona solo se si utilizza il box automatico o il metodo statico Integer.valueOf().La chiamata al costruttore genera sempre una nuova istanza di numero intero, anche se il valore di tale istanza è compreso nell'intervallo da -128 a 127. –

+0

Qualcuno può spiegare questo fenomeno? http://ideone.com/DAI75m - perché due piccoli valori (<128) diversi l'uno dall'altro dichiarati come "non uguali"? Dato che sono entrambi memorizzati nella cache, non dovrebbero appartenere alla stessa istanza di Integer e quindi "==" restituirebbe true dal momento che sta confrontando i loro riferimenti? –

+2

@David Doria: sembri avere dei malintesi seri su cosa sia una "istanza". È fondamentalmente impossibile avere due valori diversi "appartengono alla stessa istanza di Integer". Un'istanza Object è fondamentalmente una regione di memoria. Puoi avere più istanze diverse con lo stesso valore, ma non viceversa. La cache restituirà istanze diverse per valori diversi; garantisce solo di ottenere sempre la stessa istanza per lo stesso valore. –

9

Verificare l'implementazione di Integer.valueOf(int). Restituirà lo stesso oggetto Integer per gli input inferiori a 256.

EDIT:

In realtà è -128-+127 di default come indicato di seguito.

+2

In realtà l'intervallo predefinito è -128 <= i <= 127. Sembra che ci sia una proprietà di sistema (java.lang.Integer.IntegerCache.high) che può influenzare il valore massimo di un intero per essere memorizzato nella cache . – Andreas

+0

Sì. Spiacente, da -128 a +127. Tuttavia, il punto è che i valori piccoli di i vengono memorizzati nella cache! – dty