2013-02-24 12 views
5

Classe Integer ha cache, che memorizza nella cache i valori Integer. Quindi, se utilizzo il metodo valueOf o inboxing, il nuovo valore non verrà istanziato, ma verrà prelevato dalla cache.Quanto è grande la cache dei numeri interi?

So che la dimensione della cache predefinita è 127 ma può essere estesa a causa delle impostazioni della VM. La mia domanda è: quanto è grande il valore predefinito della dimensione della cache in queste impostazioni e posso manipolare questo valore? Questo valore dipende da quale macchina virtuale uso (32 o 64 bit)?

Ora sono in fase di ottimizzazione di un codice legacy e probabilmente avrò bisogno della conversione da int a Integer.

Chiarimento: A seguito di codice che ho trovato nella sorgente Java

private static class IntegerCache { 
    static final int low = -128; 
    static final int high; 
    static final Integer cache[]; 

    static { 
     // high value may be configured by property 
     int h = 127; 
     String integerCacheHighPropValue = 
      sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); 
     if (integerCacheHighPropValue != null) { 
      int i = parseInt(integerCacheHighPropValue); 
      i = Math.max(i, 127); 
      // Maximum array size is Integer.MAX_VALUE 
      h = Math.min(i, Integer.MAX_VALUE - (-low)); 
     } 
     high = h; 

     cache = new Integer[(high - low) + 1]; 
     int j = low; 
     for(int k = 0; k < cache.length; k++) 
      cache[k] = new Integer(j++); 
    } 

    private IntegerCache() {} 
} 

public static Integer valueOf(int i) { 
    assert IntegerCache.high >= 127; 
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
     return IntegerCache.cache[i + (-IntegerCache.low)]; 
    return new Integer(i); 
} 

Quindi penso che la cache è configurabile.

+2

È nel codice sorgente Java. Le impostazioni della VM non hanno nulla a che fare con questo. –

+0

Non è da -128 a +127? Non penso che possa essere cambiato, a meno che il vm non consenta la configurazione (che non ho mai visto). – vikingsteve

+3

È possibile impostare un limite diverso con la proprietà di sistema 'java.lang.Integer.IntegerCache.high'. È tutto lì nel codice sorgente. –

risposta

11

Implementazione Java interna e non può essere configurata, l'intervallo è da -128 a 127. È possibile controllare Javadocs o semplicemente dare un'occhiata a fonti:

public static Integer valueOf(int i) { 
     final int offset = 128; 
     if (i >= -128 && i <= 127) { // must cache 
      return IntegerCache.cache[i + offset]; 
     } 
     return new Integer(i); 
} 

UPD. Sono stato sbagliato (grazie a Marco Topolnik). Tutto quanto sopra è legato alle vecchie implementazioni Java. Per Java 7 implementazione potrebbe essere raggiunto con proprietà di sistema:

-Djava.lang.Integer.IntegerCache.high=<size> 

o JVM impostazione:

-XX:AutoBoxCacheMax=<size> 

UPD. 2java.math.BigInteger ha cache con hardcoded per i valori -16 < = x < = 16. Da fonti:

private final static int MAX_CONSTANT = 16; 
    private static BigInteger posConst[] = new BigInteger[MAX_CONSTANT+1]; 
    private static BigInteger negConst[] = new BigInteger[MAX_CONSTANT+1]; 
    static { 
    for (int i = 1; i <= MAX_CONSTANT; i++) { 
     int[] magnitude = new int[1]; 
     magnitude[0] = i; 
     posConst[i] = new BigInteger(magnitude, 1); 
     negConst[i] = new BigInteger(magnitude, -1); 
    } 
    } 

    public static BigInteger valueOf(long val) { 
     // If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant 
     if (val == 0) 
      return ZERO; 
     if (val > 0 && val <= MAX_CONSTANT) 
      return posConst[(int) val]; 
     else if (val < 0 && val >= -MAX_CONSTANT) 
      return negConst[(int) -val]; 
     return new BigInteger(val); 
    } 
+0

Esiste una cache simile per [java.math.BigInteger] (http://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html)? – Pacerier

+0

Sì, lo ha. Ho aggiornato la risposta. – udalmik

1

Dal Javadoc:

public static Integer valueOf (int i)

restituisce un'istanza numero intero che rappresenta il valore int specificato. Se una nuova istanza Integer non è richiesta, questo metodo dovrebbe essere in genere utilizzato preferibilmente nel costruttore Intero (int), poiché questo metodo è che offre prestazioni di spazio e tempo significativamente migliori tramite nella cache dei valori richiesti di frequente. Questo metodo memorizza sempre nella cache valori nell'intervallo compreso tra -128 e 127 e può memorizzare nella cache altri valori al di fuori di questo intervallo.

Ma davvero non dovrebbe fare affidamento su questo o cercare di cambiare nulla di questo. Questo è un dettaglio di implementazione della JVM che non dovrebbe influenzare la tua implementazione.

+0

Mentre penso che sarebbe una cattiva idea affidarsi a questa cache, il motivo per me di evitarlo sarebbe il mio desiderio di avere il mio codice pulito. Non sono d'accordo con il tuo commento su "dettagli di implementazione"; questo non è un dettaglio di implementazione. Se è in Javadoc, è vincolante: puoi tranquillamente supporre (se sei un fan del brutto codice) che '-128' a' 127' verrà memorizzato nella cache. – Isaac

2

Per Java 7, non ero in grado di trovare nella documentazione java di Oracle è una descrizione di ciò che esattamente cambierebbe quando -XX: + AggressiveOpts viene utilizzato.Così ho eseguito un processo per determinare l'effetto che l'aggressivo ha sulle impostazioni di jvm su uno dei nostri server di app in laboratorio con la versione java: {quote} versione java "1.7.0_15" Java (TM) SE Runtime Environment (build 1.7.0_15-b03) {quote}

Il processo è quello di eseguire Java con aggressiveopts disabilitato: java -d64 -server XX: -AggressiveOpts -XX: + UnlockDiagnosticVMOptions -XX: + PrintFlagsFinal -version

Il processo è di eseguire java con aggressiveopts abilitato: java -d64 -server -XX: + AggressiveOpts -XX: + UnlockDiagnosticVMOptions -XX: + PrintFlagsFinal -version

Questo processo ha prodotto queste differenze:

AggressiveOpts bool false -> true {prodotto}

IntX AutoBoxCacheMax 128 -> 20000 {prodotto C2}

IntX BiasedLockingStartupDelay 4000 -> 500 {prodotto}

bool EliminateAutoBox false -> true { Diagnostica C2}

Problemi correlati