Згідно 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-розрядному сервері VM HotSpot, версії Java від 1.7.0_04 до 1.7.0_10 на Gentoo Linux, Debian Linux (обидві версії ядра 3.0) та MacOS Lion. Ця помилка завжди може бути відтворена за допомогою коду вище. Я не тестував цю проблему з 32-розрядним JDK або в Windows. Я вже надіслав звіт про помилку до Oracle (помилка id 7196857), і він з’явиться у відкритій базі даних про помилки Oracle через кілька днів.
Оновлення:
Oracle опублікував цю помилку у своїй публічній базі помилок: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7196857