Это стек памяти (служит кешем), который состоит из ничего, кроме статического ConcurrentHashMap (CHM).
Все входящие данные HTTP-запроса хранятся в этой ConcurrentHashMap. И есть процесс планировщика asynch, который берет данные из одного и того же ConcurrentHashMap и удаляет ключевое значение после их хранения в базе данных.
Эта система работает нормально и плавно, но просто обнаруживает по следующим критериям: память была полностью использована (2,5 ГБ), и все процессорное время было принято для выполнения GC:
-контактный HTTP-клик 1000/с
-получает тот же одновременный удар в течение 15 минут
Асинхронный процесс регистрирует оставшийся размер CHM каждый раз, когда он записывает в базу данных. CHM.size() поддерживается примерно в диапазоне от мин: 300 до макс.: 3500
Я думал, что в этом приложении есть утечка памяти. поэтому я использовал Eclipse MAT, чтобы посмотреть кучу кучи. После запуска отчета о подозрительности я получил эти комментарии от MAT:
Один экземпляр "org.apache.catalina.session.StandardManager", загруженный "org.apache.catalina.loader.StandardClassLoader @0x853f0280", занимает 2,135,429,456 (94,76%) байт. Память накапливается в одном экземпляре "java.util.concurrent.ConcurrentHashMap $Segment []", загружаемого символом "".
3,646,166 instances of java.util.concurrent.ConcurrentHashMap$Segment retain >= 2,135,429,456 bytes.
и
Length # Objects Shallow Heap Retained Heap
0 3,646,166 482,015,968 >= 2,135,429,456
Длина 0 выше я переводит ее как запись пустой длины внутри CHM (каждый раз я вызываю метод CHM.remove()). Он согласуется с количеством записей внутри базы данных, в результате создания этого дампа в базе данных находилось 3,646,166 записей.
Странный сценарий: если я приостанавливаю стресс-тест, использование в памяти кучи будет постепенно снижаться до 25 МБ. Это занимает около 30-45 минут. я повторно имитирую это приложение, и кривые выглядят аналогично графику VisualVM ниже:
Возникает вопрос:
1) Это похоже на утечку памяти?
2) Каждый удаляет вызов remove(Object key, Object value)
для удаления <key:value>
из CHM, удаляет ли этот объект объект GC?
3) Это как-то связано с настройками GC? Я добавил следующие параметры GC, но без помощи:
-XX:+UseParallelGC
-XX:+UseParallelOldGC
-XX:GCTimeRatio=19
-XX:+PrintGCTimeStamps
-XX:ParallelGCThreads=6
-verbose:gc
4) Любая идея решить это очень ценится!:)
NEW 5) Возможно ли это, потому что все мои ссылки являются твердой ссылкой? Мое понимание до тех пор, пока завершается сеанс HTTP, все те переменные, которые не являются статичными, теперь доступны для GC.
NEW Примечание. Я попытался заменить CHM на ehcache 2.2.0, но я получаю ту же проблему OutOfMemoryException. я полагаю, что ehcache также использует ConcurrentHashMap.
Спецификация сервера:
-Xeon Quad core, 8 потоков.
-4GB Память
-Windows 2008 R2
-Tomcat 6.0.29