Согласно 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 опубликовала эту ошибку в своей общедоступной базе данных ошибок: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857