Вероятные и маловероятные причины появления гейзенбагов в Java?
У меня есть классический пример Heisenbug, который вызван состоянием, которое я не видел раньше. Мое унаследованное приложение (около 100 Кбайт старого кода) не работает должным образом в конкретном экземпляре, и простое включение JPDA для удаленной отладки достаточно изменяет поведение, заставляя приложение работать правильно: ничего не делая, кроме добавления "-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=6666"в командной строке vm скрывает ошибку (с реальным соединением или без него). Учитывая, что у меня есть полностью повторяемый контрольный пример, я очень не хочу его беспокоить изменениями кода на случай, если он снова станет скрытым. И, конечно, это происходит только в производстве.
Обычно я сразу же допускаю проблему с многопоточностью, но а) поведение на 100% терпит неудачу против 100% работает и б) нет явного использования потоков в рассматриваемом пути кода. Затем наша команда пыталась придумать список других причин такого поведения, поэтому я подумал, что, возможно, групповой разум Stack Overflow может добавить еще немного.
Гейзенбагс в Java:
- Потоки: плохая синхронизация, условия гонки, неявные предположения о порядке.
- Явный код отладки / регистрации: изменения в пути к коду вызывают / предотвращают проблему. Менее часто изменения в уровне журнала могут привести к изменениям синхронизации (повторение потоков) и различиям в использовании ресурсов ввода-вывода.
- Нативные библиотеки кода могут перетаскивать не проблемы Java Heisenbug.
- Ожидая, что финализаторы будут работать предсказуемо.
- неправильные предположения о слабых ссылках.
- Предположим, что кэш фиксированного размера никогда не заполняется.
- ожидая уникальности хэш-кодов.
- Предположение, что == работает со строками (или не работает со строками, которые могут быть интернированы в некоторых случаях).
- Ошибка VM (нет, этого никогда не бывает;).
- ошибка (ы) методологии тестирования. Особенно, когда есть скрытые переменные, которые зависят от успеха теста. (похоже, это наша настоящая проблема. Успех одного теста привел к тому, что клиент запустил следующий тест, который не прошел из-за проблем с политикой. Сбой привел к запуску в режиме отладки в соответствии с политикой, что привело к успеху. вздох)
Любые другие случаи, которые стоит изучить?
Редактирует:
- да, код включения JPDA использует старый синтаксис. Я не проверял, чтобы видеть, изменяет ли использование современного синтаксиса поведение.
- Этот конкретный компьютер использует 1.8.0_45-b14 для JRE и 64-разрядную серверную виртуальную машину HotSpot (сборка 25.45-b02).
- в то время как вопрос должен быть общим, подстрекательский вопрос является реальным и актуальным. Поскольку проблема проявляется в развернутой системе, я разрываюсь между желанием оставить ее запущенной с -Xdebug в качестве обходного пути, чтобы она оставалась работающей, и желанием отследить основную ошибку и устранить ее.
- рассматриваемая неисправная программа является частью многоэтапного конвейера обработки данных - детали не должны иметь значения, но ее лучше всего понимать как отдельное приложение, которое получает некоторую информацию из базы данных, а затем использует ее для изменения некоторых файлов. Разрушающаяся часть системы, по-видимому, состоит в том, что информация из базы данных не интерпретируется должным образом - что-либо из сломанного объекта ORM или из кэша. Когда он "сломан", логика приложения, которая определяет, есть ли у него работа (на основе содержимого БД), делает неправильный выбор для всех итераций (тысячи итераций, включая множественные вызовы программы). Когда он "работает" (единственное отличие - vm работает с -Xdebug или нет), приложение делает правильный выбор для всех итераций. Это полностью соответствует этой конфигурации. Один и тот же код, работающий с разными базами данных, не дает сбоя Существуют некоторые свидетельства (предшествующие моей причастности к этому коду), что подобное поведение было замечено в прошлом, что таинственным образом начало работать после, казалось бы, незначительных изменений кода... см. "Гейзенбаг"
2 ответа
-Xdebug кажется переключателем изменения поведения. Какие параметры командной строки Java можно установить для удаленной отладки JVM? утверждает, что добавление его превращает вас из JIT во все интерпретируемое. Другие документы Java оракула ( для jrocket по общему признанию), кажется, указывают, что это медленнее по некоторой неуказанной причине и не подходит для развернутых систем.
Я могу представить различные схемы GC, возможно, вносить изменения.
У меня был случай, когда сбой был спровоцирован энергосберегающей функцией на оборудовании, которая никогда не активировалась, когда ошибка изучалась.