JFreeChart中的TimeSeries可能导致内存泄露
前段时间说到现在的项目里在用JFreeChart。昨天晚上走之前没把客户端关掉,今天中午到公司发现程序已经崩了,狂抛OutOfMemoryError。用NB的profiler跟了一下,发现是JFreeChart或者说是没有正确使用JFreeChart的TimeSeries导致的后果 TimeSeries有一个方法setMaximumItemAge:
public void setMaximumItemAge(long periods)
该方法文档如下:
- Sets the number of time units in the 'history' for the series. This provides one mechanism for automatically dropping old data from the time series. For example, if a series contains daily data, you might set the history count to 30. Then, when you add a new data item, all data items more than 30 days older than the latest value are automatically dropped from the series.
- Parameters:
periods- the number of time periods.
maximumItemAge的默认值为Long.MAX_VALUE,因此如果不设置该值的话在可预见的未来过期数据将不会被丢弃,这样会导致TimeSeries的数据越来越大,尤其是在设置axis.setAutoRange(true);和axis.setFixedAutoRange(DATA_AGE);后(将横轴设为固定长度,图表只容纳限定数目个点,视觉上就是数据从右边“推入”图表,从左侧被“推出”)。虽然视觉上数据只有那么一点,但是从图表上消失的“旧”数据并没有从series里清除,导致最终的内存不足
未使用setMaximumItemAge的堆分布,才2分钟就开始深度GC,且堆大小已经开始扩大
未使用setMaximumItemAge的对象年龄(代),曲线很陡,说明很多对象没有被回收
使用setMaximumItemAge的堆分布,堆内存占用比较缓慢,堆大小未扩大,未进行深度GC
使用setMaximumItemAge的对象年龄(代),数值很高,是因为还没有进行深度GC的原因
在此提醒正在使用JFreeChart尤其是TimeSeries的给位,千万记得设置maximumItemAge