2016-02-26 3 views
2

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

это команда для запуска приложения:

Java -server -Xms1G -Xmx1G -Dfile.encoding = UTF-8

Это карта из новой реликвии с увеличением использования RAM enter image description here он начал использовать 1140 МБ и после 8 часов закончил с 1290 МБ

Это диаграмма javasualvm кучи. enter image description here

Любые предложения?

[EDIT1] добавить свалка https://www.dropbox.com/s/1gt1i9dhjtjauf0/gameserver-20160226-2107.zip?dl=0

[EDIT2] Вот некоторые заметки из моего текущего исследования

= Как монитор памяти вне кучи добавить параметры команды

-XX:NativeMemoryTracking=detail -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics 

бега jcmd 3322 VM.native_memory summary @see https://devcenter.heroku.com/articles/java-memory-issues

= Проверка размера стека по умолчанию java -XX: + PrintFlagsFinal -version | Grep ThreadStackSize

IntX ThreadStackSize = 1024
How to reclaim the memory used by a Java thread stack?

= Понять максимальную память Макс памяти = [-Xmx] + [-XX: MaxPermSize] + количество_потоков * [- Xss] @see https://plumbr.eu/blog/memory-leaks/why-does-my-java-process-consume-more-memory-than-xmx

= Действия Уменьшить размер стеков потоков. (В теории, вы можете пойти как низко, как 64K ...)

-XX:ThreadStackSize=256 

Снизить Минимальный процент кучи бесплатно после того, как GC, чтобы избежать расширения.

-XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=10 

Теперь будет продолжать мониторинг ...

+0

Возможно, вы забыли закрыть 'Closeable', например' Connection', 'Transaction',' FileOutputStream' и т. Д. Это также может быть связано с использованием родной библиотеки. –

+0

Спасибо @ArnaudDenoyelle, но я считаю, что это будет отображаться на диаграмме использования кучи, а куча всегда ниже 400 МБ (печально) –

+1

Невозможно сказать, есть ли у вас утечка памяти из предоставленной информации. –

ответ

1

После большого количества различных типов исследований, я вернулся к Eclipse Memory analyzer и попытался еще раз ...

Но на этот раз я решил довериться отчет утечки, что говорил:

Один экземпляр "org.hibernate.internal.SessionFactoryImpl" загружен «sun.misc.Launcher $ AppClassLoader @ 0xc001 d4f8 "занимает 2.956.808 (21,05%) байт.Память накапливается в одном экземпляре «org.hibernate.internal.SessionFactoryImpl», загружаемом «sun.misc.Launcher $ AppClassLoader @ 0xc001d4f8».

Затем я перенес свое расследование в мою реализацию DAO, ожидая, что я забыл закрыть тот или иной вызов EntityManager. Это было не так, все после этого были с хорошим вызовом метода close() после использования.

Тогда я понимаю, что проблема может быть в спящем режиме в качестве проблемного объекта было SessionFactory Impl, поэтому я изменил свою реализацию DAO, чтобы очистить кэш Hibernate первого уровня каждый раз, когда я создать объект менеджер, как я wasn' t найти способ отключить его.

Конечный результат дня = ИТ РАБОТАЕТ !! :) память меняет litle и возвращается через несколько минут, но больше не растет безумным способом (1000 МБ за 24 часа).

Вот код, который я изменил, надеюсь, что он кому-то поможет.

public EntityManager getEntityManager(){ 
    if(emf == null){ 
     if (parameters == null) { 
      emf = Persistence.createEntityManagerFactory(persistenceUnitName); 
     } else { 
      emf = Persistence.createEntityManagerFactory(persistenceUnitName, parameters); 
     } 
    } else { 
     emf.getCache().evictAll(); 
    } 

    EntityManager em = emf.createEntityManager(); 
    return em; 
} 

Ключ здесь: emf.getCache() evictAll();.

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