Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Роняется jvm / 21 сообщений из 21, страница 1 из 1
17.11.2015, 23:55
    #39106088
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Я использую 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.
package javaapplication3;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.ref.SoftReference;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;

public class JavaApplication3 {
    static SoftReference< ArrayList<ByteBuffer> > sr = new SoftReference<>(new ArrayList());
    
    public static void main(String[] args) throws Exception {
        RandomAccessFile raf = new RandomAccessFile("/tmp/1.tmp", "rw");
        long sz = 10_000_000;
        raf.seek(sz);
        FileChannel fc = raf.getChannel();
        
        MappedByteBuffer mbb=null;
        for(int beg=0;;beg +=90){
            int start = (int) ((beg%sz)-90);
            if (start<0) start=0;
            
            try{
                //тут я предполагаю, что jvm подчистит sr и памяти хватит.
                //но тут же и валится
                mbb = fc.map(FileChannel.MapMode.READ_WRITE, start, 90);
            }catch(IOException ex){
                System.out.println("мы тут");
                //когда пямяти нехвататет бросается IOEception, а не OOM, но это ладно
                //подчистим же ее руками
                sr=new SoftReference<>(new ArrayList());
                return; //(1)тут смотри каменты
            }
            
            try{
                ArrayList<ByteBuffer> bbArr = sr.get();
                if (bbArr==null) {
                    bbArr = new ArrayList();
                    sr = new SoftReference<>(bbArr);
                }
                bbArr.add(mbb);
                
            }catch(OutOfMemoryError ex){
                System.out.println("Сюда мы не приходим. проблема не внутри этого try");
                return;
            }
        }
    }
    
}



Вывод:
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-ов. Просто мапятся какие-то фрагменты файла, а потом в эту же переменную мапятся другие фрагменты - я надеюсь, что старый обьект подчистится, но он иногда не подчищается.

Че делать? у оракла багтрекер же только для платных подписчиков?
...
Рейтинг: 0 / 0
18.11.2015, 01:29
    #39106109
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
chabapok, возможно тут не совсем корректно в цикле многократно запрашивать

Код: java
1.
mbb = fc.map(FileChannel.MapMode.READ_WRITE, start, 90);



Протокол предполагает наличие нескольких steps. Типа сначала создаём raf, потом нацеливаем
на него fc, потом запрашиваем mbb и потом делаем fc.close() и опционально fc.force().

Последние два steps у тебя в приложении не обозначены. Возможно это ОК. А возможно и не ОК.
Я-бы проверил.
...
Рейтинг: 0 / 0
18.11.2015, 03:04
    #39106120
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Это искусственный пример. В реальном приложении файл когда-нибудь закроется, когда приложение остановят. Можно считать, что этот файл - кольцевой буфер. Существующие либы кольцевых буферов имеют шаг минимум 1сек, у меня тот же принцип, но шагом десятки мс + свои специфичные фичи.
В процессе работы делается map какого-то фрагмента, туда какое-то время что-то пишется и делается force, или из него что-то читается. И дальше этот MappedByteBuffer больше ненужен, (в идеале хотелось бы оставить его кэше). Смысла делать fc.close() - не вижу, т.к. пишется туда что-то постоянно. Реально такое кол-во буферов, чтобы вызвать баг, редкость, которой по идее быть не должно. Но все равно, факт неприятен. То есть получается, может быть такая форма oom, при которой все накроется.

В каких-то свободных либах, кстати видел такое: через рефлексию вытягивают Cleaner и дергают очистку руками. Я не хотел так делать, потому что хотелось хранить отмапленое в SoftMap...

На компе с 16gb, кстати, реальное приложение не падает - думаю, что оно успевает подчищаться штатными средствами. Это уже когда оно упало на слабой машине - я начал проводить исследовательскую работу и нарвался на такое.

Надо пойти посмотреть как в sqlite сделано...
...
Рейтинг: 0 / 0
18.11.2015, 09:03
    #39106159
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
chabapokЧе делать? у оракла багтрекер же только для платных подписчиков?
Да с фига ли?
http://bugreport.java.com/
Внизу чекбокс и кнопка. Смело рапортуй. Хотя, предварительно, стоит поискать существующие репорты.
...
Рейтинг: 0 / 0
18.11.2015, 09:09
    #39106166
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Можно проверить на Java 7. Судя по OpenJDK в Java 8 в этой обрасти чего-то там серьезно ковыряли. Могли оставить дыр.
...
Рейтинг: 0 / 0
18.11.2015, 11:11
    #39106323
fixxer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Можно увидеть полный stacktrace с caused by от IOException?
...
Рейтинг: 0 / 0
18.11.2015, 14:22
    #39106653
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
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 - то же самое.
...
Рейтинг: 0 / 0
18.11.2015, 14:57
    #39106728
fixxer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Ну вот же ваш OOM только завернутый

Caused by: java.lang.OutOfMemoryError: Map failed


В чем тогда вопросы? Какое-то странное ожидание от этого примера. Во-первых, где гарантия, что GC в вашем цикле будет вызван? Во-вторых, если будет вызван, то где гарантия, что ArrayList под SoftReference соберется, если хипа достаточно? А если не соберется, то хук на ReferenceQueue не отработает и direct memory не освободится.
...
Рейтинг: 0 / 0
18.11.2015, 15:00
    #39106735
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
chabapok,

hs_err_pid14523.log можно приаттачить?
...
Рейтинг: 0 / 0
18.11.2015, 15:01
    #39106739
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
fixxer В чем тогда вопросы? Какое-то странное ожидание от этого примера. Во-первых, где гарантия, что GC в вашем цикле будет вызван? Во-вторых, если будет вызван, то где гарантия, что ArrayList под SoftReference соберется, если хипа достаточно? А если не соберется, то хук на ReferenceQueue не отработает и direct memory не освободится.
Так проблема не в том что память не успела собраться, а в том что вместо OOME JVM закрашилась.
...
Рейтинг: 0 / 0
18.11.2015, 15:27
    #39106803
fixxer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Blazkowiczв том что вместо OOME JVM закрашилась.

Не вместо, после нескольких последовательных ООМЕ:

chabapokНасчет return c каментом (1). На машине с 4gb если этот return убрать - раз 10 выведет "мы тут" и потом все равно упадет.


А мы выяснили, что "мы тут" это OOME завернутый в IOE.
...
Рейтинг: 0 / 0
18.11.2015, 16:44
    #39106926
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
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, вместо них там камент что они вырезаны.
...
Рейтинг: 0 / 0
18.11.2015, 16:50
    #39106937
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
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 не смогла создать поток и решила, что ну его. Всё штатно.
...
Рейтинг: 0 / 0
18.11.2015, 16:59
    #39106952
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Маленькое дополнение. Там в hs_err_pid я только что увидел, что там есть LD_LIBRARY_PATH, которое указывает на 1.8.0_60. его таким ставит Netbeans. Очевидно, это неправильно, но c 1.8.0_60 оно тоже крашится. И я только что переключил нетбинс на 1.8.0_66 - те же симптомы, так что дело не в этом.
...
Рейтинг: 0 / 0
18.11.2015, 17:05
    #39106964
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
BlazkowiczПамять засралась, Java не смогла создать поток и решила, что ну его. Всё штатно.

Мне это предположение нравится. Наверное, приблизительно все так и было. Может не поток, а какие-то внутрение нужды jvm. Выходит, не совсем и баг.
...
Рейтинг: 0 / 0
09.12.2015, 19:11
    #39124401
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Итог такой. Попытался я заслать туда багрепорт, начать решил с наиболее "мелкого" бага. Но то ли из за моего паршивого английского, то ли еще чего-то, они сочли, что этот баг является разновидностью других багов, присвоили ему JDK-8144174 и сразу закрыли его как дубликат. (по ключевым словам баги, на которые они ссылались, не находились)

С тем, что это дубликат, не согласен (меня никто не спрашивал). Да, другие баги действительно похожи. В основном, люди просят, мол, сделайте нам unmap, который можно было б дернуть руками. Ответ - мы не знаем как его сделать, по таким-то причинам. Эти причины не являются актуальными в той проблеме, о которой я сообщил им.

Хз, делать еще 1 попытку или не доставать их. Если надумаю слать им еще раз, буду слать сразу с патчем.
...
Рейтинг: 0 / 0
09.12.2015, 20:07
    #39124432
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Код: plaintext
1.
2.
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build 1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode)
Windows 7 SP1.
1. java: OOM без краха JVM;
2. java -Xmx1g: двенадцать минут процессорного времени - надоело, снял;
3. java -Xms4g: OOM без краха JVM на фоне жестокого свопинга (6Гб физической памяти).

С моей кочки зрения - вполне нормальные результаты для не вполне адекватного кода.
...
Рейтинг: 0 / 0
09.12.2015, 20:09
    #39124438
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Basil A. Sidorov3. java -Xms4g: OOM IOException
...
Рейтинг: 0 / 0
09.12.2015, 21:11
    #39124458
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Под виндой баг и у меня не проявлялся.
...
Рейтинг: 0 / 0
09.12.2015, 21:18
    #39124464
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Ну тогда, наверное, под линуксом надо (тоже) ограничивать JVM в потребляемой памяти или/и к(р)утить "ядрёные опции" на пару с лимитированием ресурсов.
...
Рейтинг: 0 / 0
10.12.2015, 00:24
    #39124532
chabapok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Роняется jvm
Я изучал исходники. В jvm есть ключик -XX:MaxDirectMemorySize, которым можно ограничить кол-во потребляемой внешней памяти. Но вот беда, он работает с ByteBuffer.allocateDirect, а то что мэпится из фалов, он не учитывает.

Так же, в FileChannelImpl внутрений класс Unmapper, содержит статические поля-счетчики потребляемой замапленой памяти. Если очень хотеть - можно вытащить себе эти счетчики, можно написать свою реализацию FileChannelImpl и т.д.

Но вцелом, пожалуй, что баг ненастолько критичный, чтобы всем этим заниматься. Я на него нарвался потому, что в моей программе был вечный цикл - то есть она некорректно работала и плодила много лишнего offheаp-мусора.

Вообще, FileChannelImpl написан достаточно похабно сейчас уже так не пишут. Видно, что это legacy-код, который делался еще в допотопные времена, а потом в него добавлялись наспех костыли.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Роняется jvm / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]