Explanation of cache pool in Integer

1. Introduction

Integer buffer pooling is an optimization technique used to improve reuse and performance of integer objects. In Java, for integer values ​​in-128 to 127The integer objects between will be put into the cache pool for reuse. This is because integer values ​​in this range are used frequently, so reusing these objects saves memory and improves performance. When using the autoboxing mechanism to create an integer object, if the value of the object is within the cache pool range, the object in the cache pool will be returned directly instead of creating a new object. This feature can be achieved by calling the Integer.valueOf(int) method.

The maximum value of the cache can be modified by setting JVM-XX:AutoBoxCacheMax=, but the minimum value cannot be changed.

2. Implementation principle

The underlying implementation principle is that when int is automatically boxed, IntegervalueOf is called and IntegerCache is used.

    public static Integer valueOf(String s) throws NumberFormatException {
    
    
        return Integer.valueOf(parseInt(s, 10));
    }

There are not many complicated steps, you just need to determine whether the given value is within the specified range, and if so, obtain the pre-initialized cache value from IntegerCache.

These cached values ​​are initialized in static blocks.

/**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    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) {
    
    
                try {
    
    
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
    
    
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            //创建要缓存的值
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {
    
    }
    }

There is another interesting interview question here, that is, in the Integer class, two Integer objects with values ​​within 127 will be considered equal, while values ​​exceeding 127 are not equal. This is because in Java, for integer objects with values ​​between -128 and 127, pre-initialized objects in IntegerCache are used. So when the numeric values ​​are within that range, they are actually the same object and therefore the equality comparison returns true. This behavior applies not only to the Integer class but also to the Long class.

    public static Long valueOf(long l) {
    
    
        final int offset = 128;
        if (l >= -128 && l <= 127) {
    
     // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

For decimal types Float and Double, there is no caching mechanism like integer types. Because decimal types have a very wide range of values, it is impossible to pre-cache all possible values ​​in advance. Therefore, for objects of type Float and Double, equality comparisons are based on their actual values ​​rather than on references to the objects. Therefore, even if two Float or two Double objects have the same numerical value, they are not considered equal.

3. Modify the cache range

IntegerCache

It can be seen from the comments that the cached value can be modified

IntegerCache

Authentication: by default

integer

Add JVM parameter -XX:AutoBoxCacheMax=500

AutoBoxCacheMax

Execute again:

integer
It is found that i1 and i2 are equal and returns true, indicating that the parameters are effective.

Guess you like

Origin blog.csdn.net/qq_39939541/article/details/132309110