Нечасто мне в последнее время приходится писать код. Думал в это воскресенье быстренько напишу за часок нужную мне вещь, но не тут то было. Все написал, все отлично, но иногда программа падала на разных ассертах и непонятно из-за чего. А вроде все детерминированно - в яве проблем с неициализированной памятью нет, никаких коллекций с негарантированным порядком обхода я не использовал... в основном использовались только циклы и массивы.
В итоге убил пол дня на дебаг нестабильной программы, и оказалось баг в JVM! Если в функцию передаешь Integer.MAX_VALUE и пытаешься его использовать справа в сравнении на меньше или равно, в цикле, иногда возвращается false.
Вот минимальный код на котором происходит проблема.
Выводит примерно следующее:
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03-307, mixed mode)
Был бы благодарен, если бы кто-нибудь потестил под разными системами - винда, линукс и отписался о результатах указывая OS и Java version.
UPD: спасибо всем откликнувшимся. видимо проблема в 64-битной JVM, проявляется на всех платформах. баг репорт отправлен в оракл, проходит скрининг http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7007863.
В итоге убил пол дня на дебаг нестабильной программы, и оказалось баг в JVM! Если в функцию передаешь Integer.MAX_VALUE и пытаешься его использовать справа в сравнении на меньше или равно, в цикле, иногда возвращается false.
Вот минимальный код на котором происходит проблема.
1 public class Test {
2
3 public static void main(String[] args) {
4 for (int i = 0; ; i++) {
5 try {
6 go(Integer.MAX_VALUE);
7 } catch (Exception e) {
8 System.err.println("Failed after " + i + " iterations");
9 throw new IllegalStateException(e.getMessage());
10 }
11 }
12 }
13
14 private static void go(int maxSteps) {
15 int count = 1;
16 while (count <= maxSteps) {
17 if (count >= 10) {
18 break;
19 }
20 count++;
21 }
22
23 if (count != 10) {
24 throw new IllegalStateException("Count = " + count);
25 }
26
27 }
28
29 }
Выводит примерно следующее:
Failed after 2402 iterationsJava:
Exception in thread "main" java.lang.IllegalStateException: Count = 2
at Test.main(Test.java:9)
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04-307-10M3261)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03-307, mixed mode)
Был бы благодарен, если бы кто-нибудь потестил под разными системами - винда, линукс и отписался о результатах указывая OS и Java version.
UPD: спасибо всем откликнувшимся. видимо проблема в 64-битной JVM, проявляется на всех платформах. баг репорт отправлен в оракл, проходит скрининг http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7007863.
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode)
Все работает
Failed after ~8000 iterations, Count=2.
Забавно :)
Failed after 910 iterations
Exception in thread "main" java.lang.IllegalStateException: Count = 2
at main.main(main.java:9)
java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) 64-Bit Server VM (build 19.0-b09, mixed mode)
Failed after 5912 iterations
Прошу прощения за дубль. Внутренний ID бага 1939808, отпишусь, когда получу нормальный ID.
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
не воспроизводится :(
Может, стоит куда-нибудь эту тему повесить, чтобы кто-нибудь еще не напоролся во время контеста? Хотя тут такие условия воспроизведения жуткие.
я практически писал олимпиадную задачу. у меня была функция, которая должна была из клетки (X,Y) идти по квадратному полю в направлении (DX, DY), но делать не более чем K шагов. снаружи в функцию я передавал K, а когда мне нужно было дойти до границ поля то передавалась бесконечность в качестве K (Integer.MAX_VALUE) и функция выходила по другому условию.
так что это пример из реальной жизни. в общей сложности потрачено 5 часов чтобы изолировать проблему.
в качестве workaround можно использовать < вместо <=, или использовать число меньшее Integer.MAX_VALUE
More information is available at -http://developers.sun.com/resources/bugsFAQ.html#s4q2