Вопрос-ответ

Why Integer class caching values in the range -128 to 127?

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

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

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

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

В документации также указано: ".. и может кэшировать другие значения за пределами этого диапазона."

Как этого можно достичь?

Переведено автоматически
Ответ 1

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

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


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


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


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


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



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

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


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


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

Ответ 2

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

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

Ответ 3

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

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

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

Ответ 4

Максимальное большое целое значение, которое может быть кэшировано, может быть настроено с помощью системного свойства, т.е. 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() {}
}
java