В соответствии с JLS массив int
должен быть заполнен нулями сразу после инициализации. Однако я столкнулся с ситуацией, когда это не так. Такое поведение происходит сначала в JDK 7u4, а также во всех последующих обновлениях (я использую 64-битную реализацию). Следующий код вызывает исключение:
public static void main(String[] args) {
int[] a;
int n = 0;
for (int i = 0; i < 100000000; ++i) {
a = new int[10];
for (int f : a)
if (f != 0)
throw new RuntimeException("Array just after allocation: "+ Arrays.toString(a));
Arrays.fill(a, 0);
for (int j = 0; j < a.length; ++j)
a[j] = (n - j)*i;
for (int f : a)
n += f;
}
System.out.println(n);
}
Исключение возникает после того, как JVM выполняет компиляцию блока кода и не возникает с флагом -Xint
. Кроме того, оператор Arrays.fill(...)
(как и все остальные операторы этого кода) необходим, и исключение не возникает, если оно отсутствует. Понятно, что эта возможная ошибка ограничена некоторой оптимизацией JVM. Любые идеи по причине такого поведения?
Обновление:
Я вижу это поведение на 64-битной серверной версии HotSpot, версии Java от 1.7.0_04 до 1.7.0_10 на Gentoo Linux, Debian Linux (как версии ядра 3.0), так и MacOS Lion. Эта ошибка всегда может быть воспроизведена с помощью приведенного выше кода. Я не тестировал эту проблему с 32-разрядным JDK или Windows. Я уже отправил отчет об ошибке в Oracle (идентификатор ошибки 7196857), и он появится в общедоступной базе данных Oracle Oracle за несколько дней.
Обновление:
Oracle опубликовала эту ошибку в своей общей базе данных ошибок: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857