我有一个长时间运行的Java服务(Jetty / CometD),它有一个内存泄漏(主题为另一天),所以堆随着时间的推移相当稳定/一致(但不同的构建/设置等)
我正在研究堆大小的样本(每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);
}
所以我有一张Map可以让我随着时间的推移绘制堆大小,随着时间的推移几乎呈线性增长非常明显。
我的问题是计算堆大小的平均变化率(在我的情况下增加/增长)的最佳方法是每小时X MB(或每Y单位时间X MB)
目前我只是在javascript中对整个数据集进行排序并给出一些粗略的估计,比如过去24小时内堆大小的变化(取当前堆,减去24小时前的堆),或计算变化在过去的24小时内每小时都有这些等等。
显然,这可能非常不准确,尤其是在堆达到初始堆大小之前开始调整自身大小(使用 -Xms512m -Xmx14g 标志),并且堆大小的波动可以理解为当对堆进行采样时,没有真正的方法可以知道它是在GC之前,之前还是在中间的某个地方(原因我想计算堆增长的平均速率,如每小时50 MB或这些方面的东西。)
这样做有简单或半标准的方法吗?不一定非常准确,但寻找比我正在处理的当前方式更好的东西(和Java原生)...谢谢
答案 0 :(得分:1)
您要找的是线性趋势线或最适合行。这些条款将帮助您谷歌。
粗略地说,您需要选择一个平均算法,以便将您的一系列点数减少到两个点,然后您的MB /时间数将基本上是连接这两个点的线的斜率。
你的平均算法可以是滑动窗口算法,这是另一种说法,它可能只考虑最后N小时的数据。
当然这将是不准确的,特别是在图表的开头,我看到了大起大落。但这种不准确是生活中的事实。您需要等待一段时间才能拥有足够大的数据集,然后才能获得任何准确性。