JFreeChart - Java Heap Space issue

只愿长相守 提交于 2019-12-02 09:49:23
trashgod

For reference, I profiled two long running time series DTSCTest and MemoryUsageDemo. To exaggerate the scale, I used an artificially small heap, as shown below. In each case, I saw the typical saw-tooth pattern of periodic garbage collection return to baseline, as shown here. In contrast, this pathological example shows a secular rise in consumed memory from unrecoverable resources.

$ java -Xms32m -Xmx80m -cp build/classes:dist/lib/* chart.DTSCTest
$ java -Xms32m -Xmx80m -jar jfreechart-1.0.14-demo.jar

I resolved my problem.

I took the clue from @TrashGod to use dispose(). But it does not work directly for me.

I was adding the chart panel directly to my main JFrame container. And in my case, I wanted to keep creating the charts in the same JFrame container over and over.

I first tried clearing the dataset and called removeall() on the chart panel, but it did not help.

Then the solution I found was to create another JFrame and add the chart panel to it. And when I closed this JFrame, I again clear the dataset and called removeall() on the chart panel and also called dispose(). So everytime, I create a new chart, this JFrame and its children componenets are created and are completely disposed when I exit this JFrame.

So, when a chart is created a new JFrame is created and then disposed.

I should also add that after making this change I started to see the Saw Tooth pattern in the Java VisualVM profiler. I also used Jprofiler and I was shocked to see more than 100,000 objects were created while I was running my program. Now, I see 9000 objects created and it remains constant for the JFree package and based on my resultset retrieved the number of objects in my database package increases or decreases.

One more thing I did was to make my SQL do the parsing and convert it to a number. I wanted to reduce the number of objects created and also reduce the processing done by my program for each retrieved record.

Your solution is great! :)) Thanks to you, I have fixed my heap overflow problem. But, your solution can be even better. :)) Before you draw your graph onto panel, just call method panel.RemoveAll(); and everything that was before on your panel will be disposed. No other JFrame instances are necessary... In my case, solution was:

for(...)
{

    panel.RemoveAll();

    drawData(listOfData);

}

Have a nice day! :)

In the method org.jfree.chart.axis.DateAxis.refreshTicksHorizontal, I added following extra lines to successfully avoided the OutOfmemoryError. the reason is for some circumstance, the variable tickDate is not increased, so the loop of "while (tickDate.before(upperDate))" becomes an infinite loop.

protected List refreshTicksHorizontal(Graphics2D g2,
            Rectangle2D dataArea, RectangleEdge edge) {

    List result = new java.util.ArrayList();

    Font tickLabelFont = getTickLabelFont();
    g2.setFont(tickLabelFont);

    if (isAutoTickUnitSelection()) {
        selectAutoTickUnit(g2, dataArea, edge);
    }

    DateTickUnit unit = getTickUnit();
    Date tickDate = calculateLowestVisibleTickValue(unit);
    Date upperDate = getMaximumDate();

    boolean hasRolled = false;
    Date previousTickDate=null;            //added 
    while (tickDate.before(upperDate)) {
        if(previousTickDate!=null && tickDate.getTime()<=previousTickDate.getTime()){  //added 
            tickDate=new Date(tickDate.getTime()+100L); //added 
        }  //added 
        previousTickDate=tickDate; //added 
        //System.out.println("tickDate="+tickDate+" upperDate="+upperDate);**  //add to see infinite loop
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!