Почему целочисленные значения кэширования классов находятся в диапазоне от -128 до 127?

java caching

17842 просмотра

5 ответа

2226 Репутация автора

Что касается моего предыдущего Вопроса, почему сравнения == с Integer.valueOf (String) дают разные результаты для 127 и 128? , мы знаем, что Integer classесть кеш, который хранит значения между -128и 127.

Просто интересно, а почему между -128 и 127 ?

В документации Integer.valueOf () указано, что она « кэширует часто запрашиваемые значения » . Но значения между -128и 127часто запрашиваются для реального? Я думал, что часто запрашиваемые значения очень субъективны.
Есть ли какая-то возможная причина этого?

Из документации также говорится: «..и может кэшировать другие значения вне этого диапазона »
Как это может быть достигнуто?

Автор: DnR Источник Размещён: 03.01.2014 05:16

Ответы (5)


21 плюса

111784 Репутация автора

От -128 до 127 - размер по умолчанию. Но Javadoc также говорит, что размер кеша Integer может контролироваться этой -XX:AutoBoxCacheMax=<size>опцией. Обратите внимание, что он устанавливает только высокое значение, низкое значение всегда равно -128. Эта функция была введена в 1.6.

Почему от -128 до 127 - это диапазон значений байтов, и естественно использовать его для очень маленького кэша.

Автор: Evgeniy Dorofeev Размещён: 03.01.2014 05:20

3 плюса

49 Репутация автора

Максимальное целочисленное значение, которое можно кэшировать, можно настроить с помощью системного свойства ie 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() {}
}
Автор: theexamtime Размещён: 03.01.2014 05:30

104 плюса

263942 Репутация автора

Решение

Просто интересно, а почему между -128 и 127?

Можно кэшировать больший диапазон целых чисел , но по крайней мере те, которые находятся между -128 и 127, должны быть кэшированы, потому что это предписано Спецификацией языка Java (выделено мной):

Если значение p в штучной упаковке имеет значение true, false, байт или символ в диапазоне от \ u0000 до \ u007f, или int или короткое число в диапазоне от -128 до 127 (включительно) , то пусть r1 и r2 будут результатами любые два преобразования бокса р. Это всегда тот случай, когда r1 == r2.

Обоснование этого требования объясняется в том же пункте:

В идеале, упаковывая данное примитивное значение p, всегда получал бы одинаковую ссылку . На практике это может оказаться невозможным с использованием существующих методов реализации. Приведенные выше правила являются прагматическим компромиссом. Последнее предложение выше требует, чтобы определенные общие значения всегда помещались в неразличимые объекты. [...]

Это гарантирует, что в большинстве распространенных случаев поведение будет желаемым, без наложения чрезмерного снижения производительности, особенно на небольших устройствах . Реализации с меньшим объемом памяти могут, например, кэшировать все значения типа char и short, а также значения типа int и long в диапазоне от -32K до + 32K.


Как я могу кэшировать другие значения за пределами этого диапазона.?

Вы можете использовать -XX:AutoBoxCacheMaxопцию JVM, которая на самом деле не задокументирована в списке доступных опций Hotspot JVM . Однако это упоминается в комментариях внутри Integerкласса вокруг строки 590 :

Размер кэша может контролироваться -XX:AutoBoxCacheMax=<size>опцией.

Обратите внимание, что это зависит от реализации и может быть или не быть доступным на других JVM.

Автор: assylias Размещён: 06.01.2014 10:52

5 плюса

7501 Репутация автора

Причина кеширования маленьких целых чисел, если это то, что вы спрашиваете, состоит в том, что многие алгоритмы используют маленькие целые числа в своих вычислениях, поэтому избегание затрат на создание объекта для этих значений имеет смысл.

Тогда возникает вопрос, какие целые числа кэшировать. Опять же, говоря в целом, частота, с которой используются постоянные значения, имеет тенденцию к уменьшению при увеличении абсолютного значения константы - все проводят много времени, используя значения 1, 2 или 10, относительно немногие используют значение 109 очень интенсивно; у меньшего числа производительность будет зависеть от того, насколько быстро можно получить целое число для 722. Java решила выделить 256 слотов, охватывающих диапазон значения байта со знаком. Это решение, возможно, было основано на анализе существующих в то время программ, но с такой же вероятностью оно было чисто произвольным. Это разумное количество места для инвестиций, к нему можно быстро получить доступ (маска, чтобы узнать, находится ли значение в диапазоне кеша, затем быстрый поиск в таблице для доступа к кешу), и оно определенно охватит самые распространенные случаи.

Другими словами, я думаю, что ответ на ваш вопрос таков: «это не так субъективно, как вы думали, но точные границы в значительной степени основаны на эмпирическом решении ... и экспериментальные данные свидетельствуют о том, что он достаточно хорош. "

Автор: keshlam Размещён: 13.01.2014 01:50

0 плюса

8001 Репутация автора

Когда вы сталкиваетесь с классом Integer и всегда заключаете его в диапазон от -128 до 127, всегда лучше преобразовать объект Integer в значение int, как показано ниже.

<Your Integer Object>.intValue()
Автор: Teja Размещён: 11.03.2018 04:14
Вопросы из категории :
32x32