2017-01-25 9 views
1

У нас есть приложение Java как долго выполняющиеся службы (фактическое до времени для этой виртуальной машины Java 31 дней 3 часа 35 мин)JVM утечка памяти вне кучи и пулов буферов

Благодаря окнам Taskmanager процесса использует 1075384320 B - почти один ГБ.

Heap размера виртуальной машины Java ограничиваются 256 МБ (-Xmx256m)

данные памяти

Memory: 
Size: 268,435,456 B 
Max: 268,435,456 B 
Used: 100,000,000 up to 200,000,000 B 

- нет утечки здесь

буферных пулов

Direct: 
Count: 137 
Memory Used and Total Capacity: 1,348,354 B 

Mapped: 
Count: 0 
Memory Used and Total Capacity: 0 B 

- нет утечки здесь

мой вопрос: где же JVM использует дополнительную память?

Дополнительная информация:

Java: version 1.8.0_74 32 bit (Oracle) 

Classes: 
Total loaded: 17,248 
Total unloaded: 35,761 

Threads: 
Live: 273 
Live peak: 285 
Daemon: 79 
Total started: 486,282 

После перезагрузки он занимает несколько дней для размера процесса расти, поэтому, конечно, очередной перезагрузки поможет, и, возможно, используя более новую версию Java также может решить проблему , но я хотел бы получить объяснение этого поведения, например. г. известная ошибка в 1.8.0 до 111, зафиксированная в ... - Я еще ничего не нашел.

Мы используем около 350 таких установок в разных местах, поэтому изменение не так просто.

+0

Взгляните на используемую память с помощью jvisualvm. Вы находите его в JDK_HOME/bin. Затем вы можете рассчитать живые примеры ваших занятий. –

+0

Что вы думаете, куда я иду выше данных? –

+0

Как вы видите выше загруженные классы - 17.248; Metaspace потребляет около 58 M. –

ответ

0

Не забудьте запустить JVM в режиме сервера при выполнении длительных задач!

Причиной утечки памяти такого типа была работа JVM в клиентском режиме. Наши решения работают в нескольких сетевых магазинах на старых 32-разрядных ПК с Windows XP. По умолчанию для JVM на этой платформе находится клиентский режим.

В большинстве случаев мы запускаем JRE 1.8.0_74-32bit. С нашим приложением эта JVM утечка памяти в «Thread Arena Space» - кажется, ничего не возвращается.

После переключения в режим сервера, установив параметр -server на запуск JVM, проблемы исчезли.

0

Есть две общие причины для потребления вне кучи памяти:

  • Ваше приложение или одна из библиотек, которые вы используете (например, драйвер JDBC) выполнить что-то изначально (модуль вызывается через JNI)
  • В вашем приложении или в одной из библиотек используется автономная память другими способами, то есть с прямыми буферами или с некоторым «умным» использованием sun.misc.Unsafe.

Вы можете проверить это отслеживать нативный использование памяти с jcmdas explained here (вам необходимо перезапустить приложение).

+1

Буферные пулы (прямой или управляемый) могут контролироваться JVisualvm или JConsole (MBeans) - очень малое использование памяти. «Собственная виртуальная память» в JConsole и размер в taskmanager совпадают, поэтому JVM «знает» память, которую он потребляет. Я запустил некоторые из установок с включенным отслеживанием «родной памяти», и я надеюсь найти таким образом область памяти. –

+0

Ожидая, когда мои новые процессы станут большими, я проанализировал еще один большой процесс с VMMap от Sysinternals. Существуют большие блоки (несколько 300 МБ) «частных данных» между DLL. Завтра я буду делать некоторые объяснения. –

+0

К сожалению, я больше не знаком с управлением памятью на платформе Windows ... –