Integerでのキャッシュプールの説明

1. はじめに

整数バッファー プーリングは、整数オブジェクトの再利用とパフォーマンスを向上させるために使用される最適化手法です。Javaでは、整数値の場合、-128~127間の整数オブジェクトは再利用のためにキャッシュ プールに入れられます。これは、この範囲の整数値が頻繁に使用されるため、これらのオブジェクトを再利用するとメモリが節約され、パフォーマンスが向上します。オートボクシング メカニズムを使用して整数オブジェクトを作成する場合、オブジェクトの値がキャッシュ プールの範囲内にある場合は、新しいオブジェクトを作成する代わりに、キャッシュ プール内のオブジェクトが直接返されます。この機能は、Integer.valueOf(int) メソッドを呼び出すことで実現できます。

キャッシュの最大値は JVM-XX:AutoBoxCacheMax= を設定することで変更できますが、最小値は変更できません。

2. 実施原則

基本的な実装原則は、int が自動的にボックス化されると、IntegervalueOf が呼び出され、IntegerCache が使用されるということです。

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

複雑な手順はそれほど多くなく、指定された値が指定範囲内にあるかどうかを判断し、範囲内にある場合は、IntegerCache から事前に初期化されたキャッシュ値を取得するだけです。

これらのキャッシュされた値は静的ブロックで初期化されます。

/**
     * 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() {
    
    }
    }

ここで別の興味深いインタビューの質問があります。つまり、Integer クラスでは、127 以内の値を持つ 2 つの Integer オブジェクトは等しいとみなされますが、127 を超える値は等しくありません。これは、Java では、-128 から 127 までの値を持つ整数オブジェクトの場合、IntegerCache 内の事前に初期化されたオブジェクトが使用されるためです。したがって、数値がその範囲内にある場合、それらは実際には同じオブジェクトであるため、等価比較は true を返します。この動作は、Integer クラスだけでなく Long クラスにも当てはまります。

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

10 進数型の Float および Double には、整数型のようなキャッシュ メカニズムがありません。10 進数型の値の範囲は非常に広いため、考えられるすべての値を事前にキャッシュすることは不可能です。したがって、Float 型および Double 型のオブジェクトの等価比較は、オブジェクトへの参照ではなく、実際の値に基づいて行われます。したがって、2 つの Float オブジェクトまたは 2 つの Double オブジェクトが同じ数値を持つ場合でも、それらは等しいとはみなされません。

3. キャッシュ範囲を変更する

整数キャッシュ

コメントから、キャッシュされた値は変更できることがわかります。

整数キャッシュ

認証: デフォルト

整数

JVM パラメータを追加 -XX:AutoBoxCacheMax=500

AutoBoxCacheMax

再度実行します。

整数
i1 と i2 が等しいことがわかり、true が返され、パラメータが有効であることが示されます。

おすすめ

転載: blog.csdn.net/qq_39939541/article/details/132309110