2014-09-25 4 views
7

Наши недавние наблюдения за нашей производственной системой говорят о том, что использование памяти резидентов нашей платформы растет. Что касается этой проблемы, мы сделали некоторые исследования, чтобы понять, почему процесс Java потребляет гораздо больше памяти, чем кучи + потоки + общие объекты + кэш кода + и т. Д., Используя некоторые собственные инструменты, такие как pmap. В результате этого, мы обнаружили некоторые блоки 64M памяти (в парах), выделенные нативным процесс (возможно с таНосом/ттаром):Расширение использования памяти резидентов (RSS) Java-процесса

0000000000400000  4K r-x-- /usr/java/jdk1.7.0_17/bin/java 
0000000000600000  4K rw--- /usr/java/jdk1.7.0_17/bin/java 
0000000001d39000 4108K rw--- [ anon ] 
0000000710000000 96000K rw--- [ anon ] 
0000000715dc0000 39104K ----- [ anon ] 
00000007183f0000 127040K rw--- [ anon ] 
0000000720000000 3670016K rw--- [ anon ] 
00007fe930000000 62876K rw--- [ anon ] 
00007fe933d67000 2660K ----- [ anon ] 
00007fe934000000 20232K rw--- [ anon ] 
00007fe9353c2000 45304K ----- [ anon ] 
00007fe938000000 65512K rw--- [ anon ] 
00007fe93bffa000  24K ----- [ anon ] 
00007fe940000000 65504K rw--- [ anon ] 
00007fe943ff8000  32K ----- [ anon ] 
00007fe948000000 61852K rw--- [ anon ] 
00007fe94bc67000 3684K ----- [ anon ] 
00007fe950000000 64428K rw--- [ anon ] 
00007fe953eeb000 1108K ----- [ anon ] 
00007fe958000000 42748K rw--- [ anon ] 
00007fe95a9bf000 22788K ----- [ anon ] 
00007fe960000000 8080K rw--- [ anon ] 
00007fe9607e4000 57456K ----- [ anon ] 
00007fe968000000 65536K rw--- [ anon ] 
00007fe970000000 22388K rw--- [ anon ] 
00007fe9715dd000 43148K ----- [ anon ] 
00007fe978000000 60972K rw--- [ anon ] 
00007fe97bb8b000 4564K ----- [ anon ] 
00007fe980000000 65528K rw--- [ anon ] 
00007fe983ffe000  8K ----- [ anon ] 
00007fe988000000 14080K rw--- [ anon ] 
00007fe988dc0000 51456K ----- [ anon ] 
00007fe98c000000 12076K rw--- [ anon ] 
00007fe98cbcb000 53460K ----- [ anon ] 

интерпретировать строку с 0000000720000000 3670016K относится к куче пространству, из которых размер, который мы определяем с использованием параметра JVM «-Xmx». Сразу после этого начинаются пары, из которых сумма равна 64M. Мы используем 64-разрядную арку CentOS версии 5.10 (Final) и JDK 1.7.0_17.

Вопрос в том, что это за блокировки? Какая подсистема выделяет их?

Обновление: Мы не используем JIT-код и/или JNI-код.

+0

Вы профилировали ваше приложение Java с помощью VisualVM или аналогичного? –

+0

С VisualVM вы можете отслеживать только внутри кучи. –

ответ

10

Я столкнулся с той же проблемой. Это известная проблема с Glibc> = 2,10

Излечение является установка этой переменной ENV export MALLOC_ARENA_MAX=4

IBM статью об установке MALLOC_ARENA_MAX https://www.ibm.com/developerworks/community/blogs/kevgrig/entry/linux_glibc_2_10_rhel_6_malloc_may_show_excessive_virtual_memory_usage?lang=en

Google для MALLOC_ARENA_MAX или искать его на SO найти много ссылок.

Вы можете настраивать также другие варианты таНоса для оптимизации низкой фрагментации выделенной памяти:

# tune glibc memory allocation, optimize for low fragmentation 
# limit the number of arenas 
export MALLOC_ARENA_MAX=2 
# disable dynamic mmap threshold, see M_MMAP_THRESHOLD in "man mallopt" 
export MALLOC_MMAP_THRESHOLD_=131072 
export MALLOC_TRIM_THRESHOLD_=131072 
export MALLOC_TOP_PAD_=131072 
export MALLOC_MMAP_MAX_=65536 
+0

Так мы решили проблему. Thx для вашего ответа. –

+3

В Java 8 есть ошибка JVM, которая приводит к неограниченному росту собственной памяти: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8164293 - Если это влияет на вас, используя 'MALLOC_ARENA_MAX' может замедлить рост памяти, но не решить проблему полностью. – outofcoffee

2

Это также возможно, что есть родная утечка памяти. Общей проблемой является утечка памяти, вызванная не закрытием ZipInputStream/GZIPInputStream.

Типичный способ, которым ZipInputStream открыт является вызовом Class.getResource/ClassLoader.getResource и вызова openConnection().getInputStream() на экземпляре java.net.URL или позвонив по телефону Class.getResourceAsStream/ClassLoader.getResourceAsStream. Нужно обеспечить, чтобы эти потоки всегда закрывались.

Вы можете использовать jemalloc для отладки собственных утечек памяти, включив профилирование выборки malloc, указав параметры в переменной окружения MALLOC_CONF. Подробные инструкции доступны в этом блоге: http://www.evanjones.ca/java-native-leak-bug.html. This blog post также содержит информацию об использовании jemalloc для отладки утечки памяти в приложениях Java.

Этот же блог также содержит информацию о другом native memory leak related to ByteBuffers.

+0

Это обсуждение связано с ростом размера RSS-данных процесса Java на CloudFoundry: https://github.com/cloudfoundry/java-buildpack/issues/320#issuecomment-242350879 –

Смежные вопросы