記事ディレクトリ
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
再度実行します。
i1 と i2 が等しいことがわかり、true が返され、パラメータが有効であることが示されます。