powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Роняется jvm
21 сообщений из 21, страница 1 из 1
Роняется jvm
    #39106088
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я использую 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
Роняется jvm
    #39106109
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chabapok, возможно тут не совсем корректно в цикле многократно запрашивать

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



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

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

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

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

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

Caused by: java.lang.OutOfMemoryError: Map failed


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

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

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

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


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

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

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

Хз, делать еще 1 попытку или не доставать их. Если надумаю слать им еще раз, буду слать сразу с патчем.
...
Рейтинг: 0 / 0
Роняется jvm
    #39124432
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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
Роняется jvm
    #39124438
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov3. java -Xms4g: OOM IOException
...
Рейтинг: 0 / 0
Роняется jvm
    #39124458
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Под виндой баг и у меня не проявлялся.
...
Рейтинг: 0 / 0
Роняется jvm
    #39124464
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну тогда, наверное, под линуксом надо (тоже) ограничивать JVM в потребляемой памяти или/и к(р)утить "ядрёные опции" на пару с лимитированием ресурсов.
...
Рейтинг: 0 / 0
Роняется jvm
    #39124532
chabapok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я изучал исходники. В jvm есть ключик -XX:MaxDirectMemorySize, которым можно ограничить кол-во потребляемой внешней памяти. Но вот беда, он работает с ByteBuffer.allocateDirect, а то что мэпится из фалов, он не учитывает.

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

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

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


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