2015-08-27 3 views
1

У меня есть приложение Java, которое широко использует память. Он сохраняет структуру данных, которая растет очень быстро и отвечает за самый большой объем используемой памяти.Как отслеживать используемую память в приложении Java?

Чтобы избежать нехватки памяти, я решил очистить структуру данных до хранилища (файла или db) и отправить его после обработки.

Проблема, с которой я сталкиваюсь, состоит в выборе времени (когда используемая память «закрыта» для достижения максимально допустимого), чтобы очистить структуру данных в репозитории. Одним из способов было бы отслеживать использование памяти данных в каждом обновлении.

  dataStructure.onUpdate(new CheckMemoryIfReachedMax() { 
       public void onUpdate(long usedMemory) { 
        if (usedMemory == MaxMemory) { 
         datastucture.flushInRepository(); 
        } 
       } 
     } 

Основная проблема в этом случае заключается в том, что не легко изменить структуру данных, чтобы отслеживать память.

Другим возможным решением было бы получить использованную память из JVM и сравнить ее с максимальной памятью.

  Runtime runtime = Runtime.getRuntime(); 
      long freeMemory = runtime.freeMemory(); 
      if (freeMemory < MaxUsedMemory) { 
       datastucture.flushInRepository(); 
      } 

В этом случае проблема в том, что использование памяти только дает подсказку о том, сколько памяти используется, в том, что мы не можем предсказать момент, когда сборщик мусора удаляет объекты. Это решение заставило бы меня чаще добавлять структуру данных в репозиторий, поэтому производительность приложения может пострадать от этого.

Есть ли общий шаблон, используемый в этих случаях? Есть ли у вас какие-либо предположения о том, какое из решений лучше подходит для решения проблемы?

+0

Может быть, развернуть второе решение для первого запуска GC ('runtime.gc()') и только скрыть, если это не освобождает значительный объем памяти? – doublep

+0

@doublep - Я не думаю, что вызов GC явно (что тоже в том, что выглядит как производственный код) - хорошая идея. – TheLostMind

+0

Отметьте [Контроль использования собственной памяти Java-приложением] (http: // stackoverflow.ком/вопросы/10754748/мониторинг собственная-память-использование-по-Java-приложение) –

ответ

1

Там нет хорошего, универсального определения «памяти, используемой JVM», лучший выбор, чтобы отслеживать размер структуры самостоятельно, извините.

Проблема заключается в том, что JVM использует память как для мусора, так и для фактических данных, и нет возможности рассказать друг другу , пока не произойдет фактическая сборка мусора. Это по дизайну и на самом деле является крупной оптимизацией.

Грязным обходным путем было бы использовать JMX для отслеживания объема памяти, освобожденного во время последней коллекции (это будет размер короткоживущего мусора). Это имеет два недостатка:

  • вы получите ложные срабатывания после того, как накопится долгоживущий мусор;
  • вы будете зависеть от конкретного сборщика мусора и настроек сборщика мусора (например, я понятия не имею, возможна ли эта схема с помощью G1).
1

Я думаю, вы должны использовать первый подход, потому что сравнение времени исполнения зависит от многих вещей. Следовательно, при использовании первого подхода и получить usedMemory объекта вы можете использовать

long getObjectSize(Object objectToSize) 

из инструментария интерфейса, чтобы получить приблизительный размер объекта.

См http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize(java.lang.Object)

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