I noticed that my application is slow.I've decided to analyze GC logs and heap dump. All of a sudden I got this:
Some JRVerticalFiller took 3.4Gb of 4Gb heap memory. It starts from TaskThread which holds JRVerticalFiller, that one holds JasperPrint, from JasperPrint hand - Collections.synchronizedList(pages), these objects are JRTemplatePrintText.
Here is a gc path from TaskThread to Object[] (this Object[] in ArrayList)
NOTE: I am using JRGzipVizualizer. Maybe this is the reason, I am not sure. As I know it generates and keeps reports in memory.
Actually I don't understand why TaskThread is still alive and why so many objects have been created. It looks like a memory leak.
***************** EDIT *******************
Actually after debugging JasperReport JRVerticalFiller I've found the method
protected SavePoint fillColumnBand(JRFillBand band, byte evaluation)
....
while (band.willOverflow()){
fillColumnBreak(evaluation, evaluation);
printBand = band.fill(columnFooterOffsetY - offsetY);
fillBand(printBand);
offsetY += printBand.getHeight();
}
....
And I got infinite loop in band.willOverflow(). It always returns true.
Related question - Jasper Reports : sub-reports are causing an infinite loop
There is a point of view that the problem is in isPrintWhenDetailOverflows flag, it should be false. Actually in my case I set it to false and it works. But unfortunately this is a magic, I don't understand how to reproduce it, and does it depend just on isPrintWhenDetailOverflows flag or not? I have many places where this flag is true, but now I am investigating what the difference between those cases.