Расширение целочисленного кеша Java

Есть общий совет использовать Integer.valueOf(int) вместо new Integer(int) из-за кэширования.

В JDK 5+ вам действительно следует использовать valueOf, потому что Integer теперь кэширует Integer объекты между -128 и 127 и может каждый раз возвращать вам один и тот же точный объект Integer(0) вместо того, чтобы тратить конструкцию объекта на совершенно новый идентичный объект Integer.

Как можно расширить диапазон?


person Trustin    schedule 14.10.2010    source источник


Ответы (5)


Вы можете использовать свойство java.lang.Integer.IntegerCache.high, чтобы увеличить размер этого кеша.
пример:

java -Djava.lang.Integer.IntegerCache.high=4096 SomeClass.class
person Daniel Teply    schedule 14.10.2010

Мои вопросы к вам:

1) Почему ваш код, создающий новые объекты Integer, причиняет вам боль? У вас есть результат профиля, которым вы хотите поделиться, чтобы доказать, что создание слишком большого количества целых чисел замедляет вашу работу? Пул объектов, вообще говоря, ПЛОХАЯ идея. Вам нужно хорошее дело, чтобы оправдать это.

2) Почему вы делаете новый Integer(int)? Если вы просто сохраните его как примитивный int, вы не только избежите «создания нового объекта». вы вообще не будете создавать никаких объектов. Автоматический бокс справится с преобразованием его в целое число, если вам это понадобится в более поздний момент времени.

* Отказ от ответственности. Я не использую НИ ОДНОГО. Я пишу код, чувствительный к производительности, но никогда не доходил до того, чтобы вручную превращать примитивный int в Integer. Я просто сохраняю значение int, когда это возможно, и позволяю автобоксу JVM, если это необходимо.

person bwawok    schedule 14.10.2010
comment
Хотя вы конкретно не отвечаете на вопрос ОП, здесь я с вами согласен на 100%. Объединение таких дешевых Объектов почти наверняка является плохой идеей. - person Waldheinz; 14.10.2010

Расширение диапазона кеша может не дать вам того, что вы хотите, но если вам действительно нужно кэшировать больший диапазон, вы можете использовать этот код вместо Integer.valueOf(int). Вам просто нужно настроить значения диапазона кеша в соответствии с желаемым диапазоном.

private static class IntegerCache 
{
    private IntegerCache(){}

    static final Integer cache[] = new Integer[-(-128) + 127 + 1];

    static 
    {
        for(int i = 0; i < cache.length; i++)
        cache[i] = new Integer(i - 128); 
    }
}

public static Integer valueOf(int i) 
{
    final int offset = 128;
    if (i >= -128 && i <= 127) // must cache 
    {
        return IntegerCache.cache[i + offset];
    }
    return new Integer(i);
}

Код взят из: http://www.owasp.org/index.php/Java_gotchas

person Alan Geleynse    schedule 14.10.2010

Вот почему был добавлен целочисленный кэш:

[...] для поддержки семантики идентификации объекта автоупаковки для значений от -128 до 127 (включительно), как того требует спецификация языка.

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

person Dan Berindei    schedule 03.04.2011

По-видимому, -XX:+AggressiveOpts устанавливает максимальное значение 20000. См. ответ на Насколько велик целочисленный кеш?

person cpurdy    schedule 07.03.2014