Java 8 gapless time series chart OutOfMemoryError with XYShapeBuilder
Opened this issue · 2 comments
Issue
I get an OutOfMemoryError
with XYShapeAnnotation
and Arrays.copyOf()
when running the demo app's gapless-time annotations case with Java 8 on Ubuntu 20.04.5 LTS.
This happens if it's compiled with JDK 8 or 11 targetting 8 AND launching it with Java 8. If I launch it with Java 11 the issue doesn't occur. If I comment out the demo app's use of XYShapeBuilder
it ceases to occur.
Java 8 Version
$ java -version
openjdk version "1.8.0_352"
OpenJDK Runtime Environment (build 1.8.0_352-8u352-ga-1~20.04-b08)
OpenJDK 64-Bit Server VM (build 25.352-b08, mixed mode)
Steps to Reproduce
sudo apt-get install openjdk-8-jdk
sudo apt-get install openjdk-11-jdk
sudo update-alternatives --config java
(select JDK 8)java -version
(confirm Java 8)cd path/to/jfreechart-builder/repo
mvn clean install
cd path/to/.m2/repository/com/jfcbuilder/jfreechart-builder-demo/VERSION
java -jar jfreechart-builder-demo-VERSION.jar
- From the Demonstrations drop-down pick the Gapless | Annotations and Markers one.
- Observe the app freezes then shows an eventual out of memory exception.
- Use the alternatives to switch to Java 11
- Launch the JAR again and pick the same annotations demo.
- Observe the app doesn't freeze and doesn't throw the exception.
I didn't test this on Windows.
Java 8 Stack trace
$ java -jar jfreechart-builder-demo-1.5.6.jar
Exception in thread "AWT-EventQueue-1" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3356)
at sun.java2d.pisces.Helpers.widenArray(Helpers.java:160)
at sun.java2d.pisces.Renderer.addLine(Renderer.java:295)
at sun.java2d.pisces.Renderer.lineTo(Renderer.java:382)
at sun.java2d.pisces.Stroker$PolyStack.pop(Stroker.java:1202)
at sun.java2d.pisces.Stroker.emitReverse(Stroker.java:423)
at sun.java2d.pisces.Stroker.finish(Stroker.java:446)
at sun.java2d.pisces.Stroker.moveTo(Stroker.java:356)
at sun.java2d.pisces.Dasher.goTo(Dasher.java:155)
at sun.java2d.pisces.Dasher.somethingTo(Dasher.java:244)
at sun.java2d.pisces.Dasher.curveTo(Dasher.java:540)
at sun.java2d.pipe.RenderingEngine.feedConsumer(RenderingEngine.java:373)
at sun.java2d.pisces.PiscesRenderingEngine.pathTo(PiscesRenderingEngine.java:484)
at sun.java2d.pisces.PiscesRenderingEngine.strokeTo(PiscesRenderingEngine.java:363)
at sun.java2d.pisces.PiscesRenderingEngine.strokeTo(PiscesRenderingEngine.java:163)
at sun.java2d.pisces.PiscesRenderingEngine.getAATileGenerator(PiscesRenderingEngine.java:562)
at sun.java2d.pipe.AAShapePipe.renderPath(AAShapePipe.java:147)
at sun.java2d.pipe.AAShapePipe.draw(AAShapePipe.java:78)
at sun.java2d.pipe.PixelToParallelogramConverter.draw(PixelToParallelogramConverter.java:148)
at sun.java2d.SunGraphics2D.draw(SunGraphics2D.java:2502)
at org.jfree.chart.annotations.XYShapeAnnotation.draw(XYShapeAnnotation.java:194)
at org.jfree.chart.plot.XYPlot.drawAnnotations(XYPlot.java:3673)
at org.jfree.chart.plot.XYPlot.draw(XYPlot.java:3048)
at org.jfree.chart.plot.CombinedDomainXYPlot.draw(CombinedDomainXYPlot.java:447)
at org.jfree.chart.JFreeChart.draw(JFreeChart.java:1160)
at org.jfree.chart.ChartPanel.paintComponent(ChartPanel.java:1452)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
Some hypotheses on why it's happening:
-
XYShapeBuilder doesn't map x-coordinates to time array indices, possibly leaving shape coordinates out of view, then with Java 8 that creates a problem?
-
Based on the exception stack trace there's a logic issue in the JDK 8 implementation where an array being copied is huge, or there is an issue with indexing?
The workarounds are:
- If running with Java 8 don't use XYShapeBuilder
- Use a later version of Java.