Java梱包クラスキャッシュ分析
3825 ワード
Integer
Integer内部には
通常、上限は127か
予め-128~127の範囲内に入れておく
Byte
Short
Long
Double、Float
なぜこの2つのクラスはキャッシュされていないのですか?意味がないため……この2つのクラスはすべて浮動小数点数を代表して、Integer、Short、Byteの中から見ることができて、キャッシュは最大256個の数を貯蓄して、キャッシュは多すぎてかえってもっと多くのメモリを占有して、浮動小数点数は小数点の後ろの数を含んで、もし256個の数をキャッシュするならば、どのように範囲を選ぶべきですか?それとも-128~127?では、126.01はどうすればいいですか.キャッシュされていません.126.10もキャッシュされていません.だから、浮動小数点数にとってキャッシュヒット率が低すぎます.キャッシュしないほうがいいです.メモリの無駄です.
Integer内部には
IntegerCache
クラスがあり、このクラスはint
型の数値をキャッシュするために使用され、デフォルトのキャッシュの範囲は-128~127であり、システム属性java.lang.Integer.IntegerCache.high
が設定されている場合、このシステム属性を取得し、その後、比較を行う.i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
通常、上限は127か
java.lang.Integer.IntegerCache.high
で、もしこのシステムの属性がInteger.MAX_VALUE - 128 - 1
よりも大きいならば、上限はInteger.MAX_VALUE - 128 - 1
です(誰がそんなに卵が痛いのは上限をこんなに高く設定しますか?).上限を決定すると、内部のキャッシュ配列が初期化されます.cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
予め-128~127の範囲内に入れておく
Integer
対象Integer.valueOf(int)
が呼び出されると、まず、入力されたint値が-128127の範囲内であるかどうかを判断し、`ImageCache`から直接`Integer`オブジェクトを取得すると、Integerを再作成するメモリオーバーヘッドが回避される.-128127の範囲内でなければ、次のような新しいInteger
が直接生成されます. 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);
}
Integer
内部にキャッシュがありますが、同じように箱詰め対象のDouble
、Long
などのタイプでキャッシュはありますか?Byte
private static class ByteCache {
private ByteCache(){}
static final Byte cache[] = new Byte[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Byte((byte)(i - 128));
}
}
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
Byte
はベースタイプbyte
の箱詰めクラスであり、byteは1バイトを表し、ちょうど-128~127であるため、Byte
の箱詰めクラスはbyte
の可能なすべての値をキャッシュしている.Short
private static class ShortCache {
private ShortCache(){}
static final Short cache[] = new Short[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Short((short)(i - 128));
}
}
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
Short
もキャッシュされている-128~127の範囲内の値であることがわかりますLong
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
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);
}
Long
内部にもキャッシュが使用されており、範囲も同様-128~127Double、Float
public static Float valueOf(float f) {
return new Float(f);
}
public static Double valueOf(double d) {
return new Double(d);
}
Double
,Float
の内部ではキャッシュが使用されず、毎回新しいオブジェクトが直接生成されていることがわかります.なぜこの2つのクラスはキャッシュされていないのですか?意味がないため……この2つのクラスはすべて浮動小数点数を代表して、Integer、Short、Byteの中から見ることができて、キャッシュは最大256個の数を貯蓄して、キャッシュは多すぎてかえってもっと多くのメモリを占有して、浮動小数点数は小数点の後ろの数を含んで、もし256個の数をキャッシュするならば、どのように範囲を選ぶべきですか?それとも-128~127?では、126.01はどうすればいいですか.キャッシュされていません.126.10もキャッシュされていません.だから、浮動小数点数にとってキャッシュヒット率が低すぎます.キャッシュしないほうがいいです.メモリの無駄です.