How large is the Integer cache?
Asked Answered
A

3

13

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.

Ambassadress answered 24/2, 2013 at 13:31 Comment(7)
It is in the Java source code. The VM settings have nothing to do with it.Cubby
Isnt it from -128 to +127? I don't think it can be changed, unless the vm allows configuration (which Ive never seen).Daltondaltonism
You can set a different limit with the system property java.lang.Integer.IntegerCache.high. It's all there in the source code.Cubby
How can I set it? System.setProperty or something else?Ambassadress
In older java versions it was not configurable. In Java 7 it is.Readus
@Don, super, thats great to know - thx!Daltondaltonism
It's strange that high is configurable but low is hardcoded.Lagena
C
19

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);
    }
Curule answered 24/2, 2013 at 13:38 Comment(1)
Is there a similar cache for java.math.BigInteger?Tacho
P
4

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}

Pulsate answered 2/4, 2013 at 19:56 Comment(0)
R
1

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.

Rabelaisian answered 24/2, 2013 at 13:33 Comment(1)
While I think it'd be a bad idea to rely on this cache, the reason for me to avoid it would be my desire to have my code clean. I disagree with your comment about "implementation detail"; this isn't an implementation detail. If it's in the Javadoc, then it's binding: you can safely assume (if you're a fan of ugly code) that -128 to 127 will be cached.Foolscap

© 2022 - 2024 — McMap. All rights reserved.