سؤال

Class Integer has cache, which caches the Integer values. So if I use method valueOf or inboxing the new value will not be instantiated, but get from the cache.

I know that the default cache size is 127 but can be extended due to VM settings. My question is: how large is the default value of cache size in these settings and can I manipulate this value? Is this value depended on which VM I use (32 or 64 bits)?

I'm now on tuning of a legacy code, and probably will need the conversion from int to Integer.

Clarification: Following code I've found in Java source

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);
}

So I think the cache is configurable.

هل كانت مفيدة؟

المحلول

Internal Java implementation and could not be configured, the range is from -128 to 127. You can check Javadocs or simply take a look at sources:

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. I was wrong (thx to Marco Topolnik). All of the above is related to older Java implementations. For Java 7 implementation could be achieved with system property:

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

or JVM setting:

-XX:AutoBoxCacheMax=<size>

UPD. 2 java.math.BigInteger has hardcoded cache for values -16 <= x <= 16. From sources:

    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);
    }

نصائح أخرى

For Java 7, I wasn’t able to find in Oracle’s java documentation is a description of exactly what would change when -XX:+AggressiveOpts is used. So I ran a process to determine the effect aggressiveopts has on jvm settings on one of our app servers in the lab that had java version: {quote} java version "1.7.0_15" Java(TM) SE Runtime Environment (build 1.7.0_15-b03) {quote}

The process is to run java with aggressiveopts disabled: java -d64 -server -XX:-AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version

The process is to run java with aggressiveopts enabled: java -d64 -server -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version

This process produced these differences:

bool AggressiveOpts false --> true {product}

intx AutoBoxCacheMax 128 --> 20000 {C2 product}

intx BiasedLockingStartupDelay 4000 --> 500 {product}

bool EliminateAutoBox false --> true {C2 diagnostic}

From the Javadoc:

public static Integer valueOf(int i)

Returns an Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.

But you really shouldn't rely on this or try to change anything about this. This is an implementation detail of the JVM which should not influence your implementation.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top