Как сопоставить дескриптор файла процесса с объектом Java

У меня есть веб-приложение, которое пропускает файловые дескрипторы. В производственной среде количество файловых дескрипторов в java-процессе со временем медленно растет, и через несколько месяцев у него заканчиваются файловые дескрипторы. Текущий лимит файловых дескрипторов довольно высок, 10240.

При взгляде на процесс Java список файловых дескрипторов выглядит следующим образом:

# ls -l /proc/32526/fd |wc -l
9558

# ls -l /proc/32526/fd
lr-x------ 1 userx userx 64 Apr 23 12:21 1229 -> /data/s1-js2-tier2-store6/52d/2ed/f73/1c80d154a055e5e
lr-x------ 1 userx userx 64 Apr 23 12:21 1230 -> /data/s1-js2-tier2-store6/52d/9aa/ad3/1c80d154a0688a6
lr-x------ 1 userx userx 64 Apr 23 12:21 1231 -> /data/s1-js2-tier2-store4/522/9c8/543/1c81a0c37763880
lr-x------ 1 userx userx 64 Apr 23 12:21 1232 -> /data/s1-js2-tier2-store6/52d/78c/4f3/1c80d154a06308c
lr-x------ 1 userx userx 64 Apr 23 12:21 1239 -> /data/s1-js2-tier2-store6/530/b88/753/1c80901a6d6541f (deleted)

Что я хотел бы сделать, так это выбрать один файловый дескриптор, а затем каким-то образом сопоставить его с объектом в работающей JVM, чтобы я мог исследовать, какие объекты остались позади и кто содержит ссылку на объекты с присоединенными файловыми дескрипторами.

Я хотел подключиться к живой JVM с помощью Eclipse, но для этого мне нужно перезапустить JVM, чтобы добавить порты/параметры отладки, но тогда мне нужно будет ждать месяцы, пока не появится такая же ситуация.

Как я могу это сделать без перезапуска JVM? Существуют ли какие-либо инструменты дампа, которые могут помочь мне в этом конкретном случае?


person ssasa    schedule 23.04.2014    source источник
comment
Ваша основная цель — найти утечку и удалить ее из исходного кода или у вас нет исходников и нужно взломать?   -  person TomasZ.    schedule 23.04.2014
comment
Основная цель - найти утечку и устранить ее. У меня есть исходный код.   -  person ssasa    schedule 23.04.2014
comment
У нас было приложение, разработанное другой компанией, и у меня была та же проблема. Не уверен, что это поможет вам, но я исправил это, используя полный поиск eclipse. Я искал FileReader и FileWriter и нашел несколько мест, где файлы были открыты и прочитаны, но никогда не закрывались. Поэтому я просто поместил его в блок try/catch/finally, и проблема исчезла. Но у вас может быть более сложная проблема. Также попробуйте поискать Input/OutputStreams или напрямую java.io. Я знаю, что это не отвечает на вопрос, но, возможно, это поможет.   -  person TomasZ.    schedule 23.04.2014
comment
Какая реализация JVM используется для размещения приложения?   -  person shroudednight    schedule 24.04.2014
comment
Sun/Oracle JDK 1.7.0_51   -  person ssasa    schedule 24.04.2014


Ответы (1)


Что вам нужно, так это дамп кучи виртуальной машины.

Если вы используете jdk 1.7, вы можете подключиться к JVM даже без предварительной настройки отладки. Вы должны иметь возможность получить дамп кучи через jmap в оболочке.

jmap -dump:format=b,file=<FILENAME> <PID> 

сделает это за вас.

После этого вы можете загрузить дамп кучи в Eclipse MAT и проанализировать оттуда. Если утечка достаточно значительна, то ее, вероятно, не очень сложно обнаружить с помощью отчетов по умолчанию.

person Michael Heß    schedule 19.02.2015
comment
Это не совсем ответ на исходный вопрос, как сопоставить дескриптор файла с java-объектом, который его содержит;) - person ssasa; 19.02.2015
comment
Вы запросили инструмент создания дампа, который может вам помочь. Хотя для этого нет единого инструмента (по крайней мере, я знаю), я думаю, что jmap + MAT поможет вам достичь вашей цели. MAT позволит вам сначала отфильтровать ссылки на файлы, а затем вы сможете пройтись по графу объектов, чтобы увидеть, кто содержит ссылку на объекты с прикрепленными файловыми дескрипторами. - person Michael Heß; 20.02.2015