03 December 2013

Integer cache

Есть такая известная задачка, что напечатает в консоль данный код:

Казалось бы очевидно - везде '127', но не все так просто. В Java для оптимизации числа объектов был разработан так называемый Integer cache (некий аналог String pool):

Аналогичный кэш существует и для оберток типа Long:

По-умолчанию размер кэша - 256 и заполнен числами в интервале [-128; 127]. Но размер можно изменить:
  • -XX:AutoBoxCacheMax=XXXX - увеличивает размер кэшей (Integer, Long) до XXXX + 128, где будут храниться значения в интервале [-128; XXXX];
  • -XX:+AggressiveOpts - опция изменяет значения множества опций, среди которых увеличивает AutoBoxCacheMax до 20 000;
  • -Djava.lang.Integer.IntegerCache.high=XXXX - данная опция по аналогии с AutoBoxCacheMax увеличивает размер кэша, только в данном случае только для объектов типа Integer.
Вся хитрость задачи, приведенной в начале, заключается в том, что с помощью рефлексии можно получить доступ к внутреннему значению Integer и изменить его:

Таким образом, мы значение '127' заменяем на '0' и код, приведенный в начале, в 1-ом и 3-ем случае выведет '0'! В 1-ом случае мы выводим измененный объект 'x', во 2-ом - будет вызван метод println(int x) и боксинг не произойдет, в 3-ем случае произойдет боксинг и возьмется значение из кэша, в 4-ом - мы явно создаем объект в обход кэша.

Такие дела,
Иван

No comments:

Post a Comment