web-dev-qa-db-ja.com

整数クラスが-128〜127の範囲の値をキャッシュするのはなぜですか?

私の以前の質問に関して、 なぜ== Integer.valueOf(String)との比較は127と128で異なる結果を与えるのか?Integerclassには-128127の間の値を保存するキャッシュ。

ただ疑問に思うのは、なぜ-128と127の間ですか?

Integer.valueOf()ドキュメンテーション はそれを述べている"頻繁に要求される値をキャッシュする"しかし、-128127の間の値は実際に頻繁に要求されますか? 頻繁に要求される値は非常に主観的だと思いました。
この背後に考えられる理由はありますか?

また、ドキュメントから:".. andこの範囲外の他の値をキャッシュできます。"
これはどのように達成できますか?

80
DnR

ちょうど疑問に思う、なぜ-128と127の間?

より広い範囲の整数mayはキャッシュされますが、少なくとも-128〜127の間はmustJava言語仕様 =(強調鉱山):

ボックス化される値pがtrue、false、バイト、または\ u0000から\ u007fの範囲の文字、または-128から127までの整数または短い数値(包括的)、r1とr2をpの2つのボクシング変換の結果とする。常にr1 == r2です。

この要件の根拠は、同じ段落で説明されています。

理想的には、特定のプリミティブ値pをボックス化すると、常に同一の参照が生成されます。実際には、これは既存の実装技術を使用して実行できない場合があります。上記のルールは実用的な妥協案です。上記の最後の節では、特定の共通値を常に区別できないオブジェクトにボックス化する必要があります。 [...]

これは、ほとんどの一般的な場合、特に小さなデバイスで過度のパフォーマンスペナルティを課すことなく、動作が望ましいものになることを保証します。たとえば、メモリ制限の少ない実装では、すべてのchar値とshort値、および-32K〜+ 32Kの範囲のint値とlong値がキャッシュされます。


この範囲外の他の値をキャッシュするにはどうすればよいですか?

-XX:AutoBoxCacheMax JVMオプションを使用できますが、これは 利用可能なHotspot JVMオプション のリストには実際には記載されていません。ただし、 行590の周りのIntegerクラス内のコメント で言及されています:

キャッシュのサイズは、-XX:AutoBoxCacheMax=<size>オプションで制御できます。

これは実装固有であり、他のJVMで使用できる場合と使用できない場合があることに注意してください。

104
assylias

-128〜127がデフォルトのサイズです。ただし、javadocでは、整数キャッシュのサイズ多分-XX:AutoBoxCacheMax=<size>オプション。高い値のみを設定し、低い値は常に-128であることに注意してください。この機能は1.6で導入されました。

なぜ-128〜127-これはバイト値の範囲であり、非常に小さなキャッシュに使用するのが自然です。

21

小さな整数をキャッシュする理由は、それがあなたが求めているものである場合、多くのアルゴリズムが計算で小さな整数を使用するため、これらの値のオブジェクト作成オーバーヘッドを回避する価値があるためです。

質問は、どの整数をキャッシュするかとなります。繰り返しますが、一般的に言えば、定数の絶対値が増加するにつれて定数値が使用される頻度は減少する傾向があります-誰もが値1または2または10を使用して多くの時間を費やします集中的に; 722の整数を取得できる速度に応じて、パフォーマンスが低下します。Java符号付きバイト値の範囲に256スロットを割り当てることを選択しました。この決定は、プログラムを分析することによって通知された可能性があります当時は存在していましたが、純粋にarbitrary意的なものであった可能性があります。投資するのに十分なスペースであり、迅速にアクセスできます(値がキャッシュの範囲内にあるかどうかを調べるマスク、そしてクイックテーブルキャッシュにアクセスするためのルックアップ)、最も一般的なケースを確実にカバーします。

言い換えれば、あなたの質問に対する答えは「あなたが思ったほど主観的ではないが、正確な限界はおおむね経験則による決定である...」そして実験的証拠はそれが十分であったということであると思う。 」

5
keshlam

キャッシュできる最大の高整数値は、システムプロパティ(Java.lang.Integer.IntegerCache.high-XX:AutoBoxCacheMax)。キャッシュは配列を使用して実装されます。

    private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            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() {}
}
3
theexamtime

Integerクラスに遭遇し、常に-128〜127の範囲内でボックス化されている場合は、Integerオブジェクトを以下のようにint値に変換することをお勧めします。

<Your Integer Object>.intValue()
0
Teja