|
|
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Я использую 1.8.0_66 (пробовал как i586, так и x64. Пробовал так же более ранние), система - xubuntu 12.04 x64 То ли мне невезет и я постоянно попадаю на баги, то ли еще что. Первая проблема заключается в том, что FileChannel.map "под капотом" работает на mmap и возвращает unmanaged-память, и там в глубине исходников (в srс.zip их нет, но если скачать с git или смотреть идеей то можно найти sun.nio.ch.FileChannelImpl.map) делается сначала маппинг, а потом делается new FileChannelImpl.Unmapper не обрамленное в try-catch. Если этот new кинет OOM, а выше это OOM будет поймано и обработано, то память останется замапленой навсегда - и будет утечка памяти. Эта проблема не очень актуальна. Когда я пытался воспроизвести ее - не получилось вызвать oom в нужном месте. Но это так, к слову. Просто вспомнилось про нее к случаю. Вторая проблема жесче. jvm нормально не справляется со случаем, когда для FileChannel.map не хватает внешней памяти - и падает. Под "нормально не справляется" я подразумеваю, что она, похоже, то ли вообще не пытается запускать gc, толи запускает лишь предварительную подчистку, которой явно недостаточно. Во всяком случае, когда я в реальном проекте нарвался на этот баг, то обнаружил, что анмаппинг такой памяти делается при помощи ReferenceQueue<sun.misc.Cleaner> - и у меня создалось впечатление, что gc не дошел до чистки хипа, и стало быть, не подхватил Cleaner-ы, а они не освободили direct-память. Но все равно от такого падать не должно. Следующий код падает, c cозданием hs_err_pid14523.log Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. Вывод: jvmмы тут Java HotSpot(TM) Server VM warning: Attempt to deallocate stack guard pages failed. # Java HotSpot(TM) Server VM warning: INFO: os::commit_memory(0xf669e000, 12288, 0) failed; error='Cannot allocate memory' (errno=12) # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 12288 bytes for committing reserved memory. # An error report file with more information is saved as: # /home/chabapok/NetBeansProjects/tests/JavaApplication3/hs_err_pid14523.log Java Result: 1 Как я понимаю, если создался hs_err_pid - то это уже ненормально. Насчет return c каментом (1). На машине с 4gb если этот return убрать - раз 10 выведет "мы тут" и потом все равно упадет. На машине с 16gb не падает, но повисает совсем, потом только kill -SIGKILL. Проверил так же на винде. На винде такого бага с jvm похоже, что нету, но все равно gc не запускается и мы попадаем периодически туда, где блок "мы тут". Что вобщем-то тоже не очень хорошо. При этом, в реальном проекте, в котором я на такое нарвался, у меня нету вообще SoftReference-ов. Просто мапятся какие-то фрагменты файла, а потом в эту же переменную мапятся другие фрагменты - я надеюсь, что старый обьект подчистится, но он иногда не подчищается. Че делать? у оракла багтрекер же только для платных подписчиков? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2015, 23:55 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
chabapok, возможно тут не совсем корректно в цикле многократно запрашивать Код: java 1. Протокол предполагает наличие нескольких steps. Типа сначала создаём raf, потом нацеливаем на него fc, потом запрашиваем mbb и потом делаем fc.close() и опционально fc.force(). Последние два steps у тебя в приложении не обозначены. Возможно это ОК. А возможно и не ОК. Я-бы проверил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 01:29 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Это искусственный пример. В реальном приложении файл когда-нибудь закроется, когда приложение остановят. Можно считать, что этот файл - кольцевой буфер. Существующие либы кольцевых буферов имеют шаг минимум 1сек, у меня тот же принцип, но шагом десятки мс + свои специфичные фичи. В процессе работы делается map какого-то фрагмента, туда какое-то время что-то пишется и делается force, или из него что-то читается. И дальше этот MappedByteBuffer больше ненужен, (в идеале хотелось бы оставить его кэше). Смысла делать fc.close() - не вижу, т.к. пишется туда что-то постоянно. Реально такое кол-во буферов, чтобы вызвать баг, редкость, которой по идее быть не должно. Но все равно, факт неприятен. То есть получается, может быть такая форма oom, при которой все накроется. В каких-то свободных либах, кстати видел такое: через рефлексию вытягивают Cleaner и дергают очистку руками. Я не хотел так делать, потому что хотелось хранить отмапленое в SoftMap... На компе с 16gb, кстати, реальное приложение не падает - думаю, что оно успевает подчищаться штатными средствами. Это уже когда оно упало на слабой машине - я начал проводить исследовательскую работу и нарвался на такое. Надо пойти посмотреть как в sqlite сделано... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 03:04 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
chabapokЧе делать? у оракла багтрекер же только для платных подписчиков? Да с фига ли? http://bugreport.java.com/ Внизу чекбокс и кнопка. Смело рапортуй. Хотя, предварительно, стоит поискать существующие репорты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 09:03 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Можно проверить на Java 7. Судя по OpenJDK в Java 8 в этой обрасти чего-то там серьезно ковыряли. Могли оставить дыр. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 09:09 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Можно увидеть полный stacktrace с caused by от IOException? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 11:11 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
fixxerМожно увидеть полный stacktrace с caused by от IOException? ex.printStackTrace дает такое: jvm java.io.IOException: Map failed at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:939) at prob2.JavaApplication3.main(JavaApplication3.java:30) Caused by: java.lang.OutOfMemoryError: Map failed at sun.nio.ch.FileChannelImpl.map0(Native Method) at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:936) ... 1 more Java HotSpot(TM) Server VM warning: Attempt to deallocate stack guard pages failed. Java HotSpot(TM) Server VM warning: INFO: os::commit_memory(0xf6713000, 12288, 0) failed; error='Невозможно выделить память' (errno=12) BlazkowiczМожно проверить на Java 7. 1.7.0_45-x64 - то же самое. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 14:22 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Ну вот же ваш OOM только завернутый Caused by: java.lang.OutOfMemoryError: Map failed В чем тогда вопросы? Какое-то странное ожидание от этого примера. Во-первых, где гарантия, что GC в вашем цикле будет вызван? Во-вторых, если будет вызван, то где гарантия, что ArrayList под SoftReference соберется, если хипа достаточно? А если не соберется, то хук на ReferenceQueue не отработает и direct memory не освободится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 14:57 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
chabapok, hs_err_pid14523.log можно приаттачить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 15:00 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
fixxer В чем тогда вопросы? Какое-то странное ожидание от этого примера. Во-первых, где гарантия, что GC в вашем цикле будет вызван? Во-вторых, если будет вызван, то где гарантия, что ArrayList под SoftReference соберется, если хипа достаточно? А если не соберется, то хук на ReferenceQueue не отработает и direct memory не освободится. Так проблема не в том что память не успела собраться, а в том что вместо OOME JVM закрашилась. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 15:01 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Blazkowiczв том что вместо OOME JVM закрашилась. Не вместо, после нескольких последовательных ООМЕ: chabapokНасчет return c каментом (1). На машине с 4gb если этот return убрать - раз 10 выведет "мы тут" и потом все равно упадет. А мы выяснили, что "мы тут" это OOME завернутый в IOE. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 15:27 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
fixxerВо-первых, где гарантия, что GC в вашем цикле будет вызван? Во-вторых, если будет вызван, то где гарантия, что ArrayList под SoftReference соберется, если хипа достаточно? А если не соберется, то хук на ReferenceQueue не отработает и direct memory не освободится. Вобщем, да. ByteBuffer.allocateDirect тоже ничего не подчищает и выбрасывает OOME - но при этом, не крашит jvm, а FileChannel.map - крашит. Blazkowiczhs_err_pid14523.log можно приаттачить? Да, аттачу. Единственное что, полный лог - 5мб, причем, размер отмапленой области почти не влияет на размер hs_err_pid, и в нем очень много строк вида "7fa6315a4000-7fa6315a5000 rw-s 00302000 08:22 3932290 /tmp/1.tmp" - я их вырежу чтобы влезть в разрешенные форумом 150kb, вместо них там камент что они вырезаны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 16:44 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
chabapok, Судя по вот этому, это не совсем баг. [SRC С]# There is insufficient memory for the Java Runtime Environment to continue. ... V [libjvm.so+0xab9a1a] VMError::report_and_die()+0x2ba V [libjvm.so+0x4f9e0b] report_vm_out_of_memory(char const*, int, unsigned long, VMErrorType, char const*)+0x8b [/SRC] Память засралась, Java не смогла создать поток и решила, что ну его. Всё штатно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 16:50 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Маленькое дополнение. Там в hs_err_pid я только что увидел, что там есть LD_LIBRARY_PATH, которое указывает на 1.8.0_60. его таким ставит Netbeans. Очевидно, это неправильно, но c 1.8.0_60 оно тоже крашится. И я только что переключил нетбинс на 1.8.0_66 - те же симптомы, так что дело не в этом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 16:59 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
BlazkowiczПамять засралась, Java не смогла создать поток и решила, что ну его. Всё штатно. Мне это предположение нравится. Наверное, приблизительно все так и было. Может не поток, а какие-то внутрение нужды jvm. Выходит, не совсем и баг. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 17:05 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Итог такой. Попытался я заслать туда багрепорт, начать решил с наиболее "мелкого" бага. Но то ли из за моего паршивого английского, то ли еще чего-то, они сочли, что этот баг является разновидностью других багов, присвоили ему JDK-8144174 и сразу закрыли его как дубликат. (по ключевым словам баги, на которые они ссылались, не находились) С тем, что это дубликат, не согласен (меня никто не спрашивал). Да, другие баги действительно похожи. В основном, люди просят, мол, сделайте нам unmap, который можно было б дернуть руками. Ответ - мы не знаем как его сделать, по таким-то причинам. Эти причины не являются актуальными в той проблеме, о которой я сообщил им. Хз, делать еще 1 попытку или не доставать их. Если надумаю слать им еще раз, буду слать сразу с патчем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2015, 19:11 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 1. java: OOM без краха JVM; 2. java -Xmx1g: двенадцать минут процессорного времени - надоело, снял; 3. java -Xms4g: OOM без краха JVM на фоне жестокого свопинга (6Гб физической памяти). С моей кочки зрения - вполне нормальные результаты для не вполне адекватного кода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2015, 20:07 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Basil A. Sidorov3. java -Xms4g: OOM IOException ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2015, 20:09 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Под виндой баг и у меня не проявлялся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2015, 21:11 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Ну тогда, наверное, под линуксом надо (тоже) ограничивать JVM в потребляемой памяти или/и к(р)утить "ядрёные опции" на пару с лимитированием ресурсов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2015, 21:18 |
|
||
|
Роняется jvm
|
|||
|---|---|---|---|
|
#18+
Я изучал исходники. В jvm есть ключик -XX:MaxDirectMemorySize, которым можно ограничить кол-во потребляемой внешней памяти. Но вот беда, он работает с ByteBuffer.allocateDirect, а то что мэпится из фалов, он не учитывает. Так же, в FileChannelImpl внутрений класс Unmapper, содержит статические поля-счетчики потребляемой замапленой памяти. Если очень хотеть - можно вытащить себе эти счетчики, можно написать свою реализацию FileChannelImpl и т.д. Но вцелом, пожалуй, что баг ненастолько критичный, чтобы всем этим заниматься. Я на него нарвался потому, что в моей программе был вечный цикл - то есть она некорректно работала и плодила много лишнего offheаp-мусора. Вообще, FileChannelImpl написан достаточно похабно сейчас уже так не пишут. Видно, что это legacy-код, который делался еще в допотопные времена, а потом в него добавлялись наспех костыли. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2015, 00:24 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=39106926&tid=2124573]: |
0ms |
get settings: |
10ms |
get forum list: |
20ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
75ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
65ms |
get tp. blocked users: |
2ms |
| others: | 244ms |
| total: | 439ms |

| 0 / 0 |
