2016-10-14 2 views
3

У меня есть длинный Java-сервис (Jetty/CometD), который имеет утечку памяти (тема для другого дня), поэтому куча постоянно увеличивается/стабильно время (но разные с разными сборки/настройки и т.д.)Java: Рассчитать среднее увеличение кучи за X единицу времени с карты <Long, Long>

Я беру образцы размером кучи в течение долгого времени (каждые 15 минут или около того) и хранить их в HashMap определены следующим образом:

// heapSizeMap uses the current timestamp for the key 
// and the size of the heap in MB as the val 
Map<Long, Long> heapSizeMap = new HashMap<>();  

и функция, которая вызывается для добавления к карте:

public void addToHeapMap() { 
    Runtime runtime = Runtime.getRuntime(); 
    int mb = 1024*1024; 

    Long currentHeap = (runtime.totalMemory() - runtime.freeMemory())/mb; 

    heapSizeMap.put(new Date().getTime(), currentHeap); 
} 

У меня есть карта, которая позволяет мне графически отображать размер кучи с течением времени, и почти линейный рост с течением времени довольно очевиден.

Heap Growth.

Мой вопрос: что было бы лучшим способом вычислить среднюю скорость изменения (увеличение/рост в моем случае) в динамической памяти как что-то вроде X МБ в час (или X МБ на Y единицу времени)

В настоящее время я просто сортирую весь набор данных в javascript и даю приблизительные оценки, такие как изменение размера кучи за последние 24 часа (с использованием текущей кучи, минус куча 24 часа назад) или вычисления изменения для каждый час за последние 24 часа и усреднение и т. д.

Очевидно, что это может быть довольно неточно, особенно до того, как куча начнет изменять размер до того, как достигнет начального размера кучи (с использованием -Xms512m -Xmx14g), а колебания в размере кучи понятны вверх и вниз, а когда выбрана куча, нет реального способа узнать, было ли это сразу после GC, как раз перед этим, или где-то посередине (причина Я бы хотел рассчитать среднюю скорость роста кучи, например, 50 МБ в час или что-то в этом роде).

Есть ли простой или полустандартный способ сделать это? Не нужно быть супер точными, но искать что-то лучше (и Java родной), чем текущий способ обработки я это ... Спасибо

+0

Почему бы не просто профилировать приложение и не исправить утечку памяти? Я бы сказал, что это пустая трата времени, если вы не создаете продукт, который касается утечек памяти или чего-то связанного. – Kayaman

+1

Похоже, вы хотите, чтобы была выполнена кривая [простая линейная регрессия] (https://en.wikipedia.org/wiki/Simple_linear_regression). Наклон результирующей линии - это MB/время, которое вы хотите. –

+0

@ Kayaman Я хотел бы исправить утечку памяти, но я проанализировал кучи кучи и использовал профилировщик YourKit, чтобы попытаться определить, где находится курящее оружие, однако до сих пор я дошел до пустого. Я до сих пор довольно новичок в этой части разработки Java и, к сожалению, не могу найти источник проблемы. Хотя я не сдаюсь, но хотел бы рассчитать рост (и, надеюсь, увидим, что все ближе и ближе к 0, поскольку я исправляю утечки) – giantNinja

ответ

1

Что вы ищете является линейной линией тренда или лучше всего подходит линия. Эти условия помогут вам Google.

Грубо говоря, вам нужно будет выбрать алгоритм усреднения, чтобы уменьшить количество точек до двух точек, а затем ваш номер MB/time будет по существу равным наклону линии, соединяющей эти две точки.

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

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

+0

Благодарим вас за лучшие поисковые запросы Google, поскольку я видел несколько способы его описания. и вы правы в аспекте неточности, особенно, когда куча имеет более широкие колебания, поэтому я ищу способ получить среднюю скорость увеличения (за определенный период времени, который я планирую хранить где-то вроде redis, поэтому я могу проанализировать его позже для сборки/конфигурации). – giantNinja

+0

нашел этот класс, чтобы помочь получить среднюю строку/склон из моих данных [LinearRegression.java] (http://algs4.cs.princeton.edu/14analysis/LinearRegression.java .html). Если я кормлю его набором данных точек (ось х - это отметки времени с пятнадцатиминутными интервалами), возвращаемый уклон является двойным, как 18.78. Как вы используете этот отстой для вычисления/выражения в единицах MB/time ... Я знаю, что это уже в основном в этой форме, но составляет 18,78 МБ за 15 минут (интервал точек данных, переданных в этот класс)? или это уже в час? – giantNinja

+0

Код, который вы связали, выглядит более сложным, чем я думал. В любом случае, я не знаю, что такое 18.78; Я не могу понять, как это работает, просто глядя на него, и я не могу/не хочу, чтобы я столкнулся с проблемой его запуска и придумывал образцы данных для его подачи. Я боюсь, что вам нужно будет предоставить ему некоторые образцы данных и посмотреть, что вы получите. Дайте ему 5 очков в пределах от 10 до 60 (то есть с шагом в 10 единиц) и посмотрите, что вы получите. –

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