JFreeChart - Java 内存泄漏

Posted

技术标签:

【中文标题】JFreeChart - Java 内存泄漏【英文标题】:JFreeChart - Java Leak memory 【发布时间】:2015-01-20 10:20:19 【问题描述】:

我第一次将 Jfreechart (jfreechart-1.0.13.jar) 与 struts1、java6、jboss4 一起使用。 我使用此代码创建图表:

private JFreeChart getJfreeChart(int product, int msg) 

        DefaultPieDataset dpd = new DefaultPieDataset();
        dpd.setValue("product", product);
        dpd.setValue("msg", msg);

        JFreeChart chart = ChartFactory.createPieChart3D(null, dpd, true, false, false);

        PiePlot plot = (PiePlot) chart.getPlot();
        plot.setSectionPaint("product", new Color(51, 102, 153));
        plot.setSectionPaint("msg", new Color(160, 218, 230));

        plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator("0"));
        plot.setLabelGenerator(new StandardPieSectionLabelGenerator("0 : 1"));

        return chart;

在我的操作中,我确实喜欢这样显示图表:

response.setContentType("image/png");
ServletOutputStream outputStream = response.getOutputStream();
ChartUtilities.writeChartAsPNG(outputStream, chart, 900, 450);
outputStream.close();

在我的jsp中,我使用<img src="MyAction.do" />来显示图表

当我执行 getJfreeChart 时,我注意到内存泄漏。 我的代码有异常吗?

java.lang.OutOfMemoryError: PermGen space
    at javax.swing.UIManager.initialize(Unknown Source)
    at javax.swing.UIManager.maybeInitialize(Unknown Source)
    at javax.swing.UIManager.getDefaults(Unknown Source)
    at javax.swing.UIManager.getColor(Unknown Source)
    at org.jfree.chart.JFreeChart.<clinit>(JFreeChart.java:261)
    at org.jfree.chart.ChartFactory.createPieChart3D(ChartFactory.java:763)

【问题讨论】:

内存不足并不一定表示“泄漏”。您的 PermGen 空间的大小设置为多少?该 JVM 实例上还运行什么? @Mikaveli :我有这个配置: -XX:PermSize=258M -XX:MaxPermSize=512M 只有应用程序在 JVM 实例上运行。 【参考方案1】:

首先,尝试增加您的 PermGen 空间。如果是真正的泄漏,您仍然会看到相同的错误,但至少应该延迟它。

另一个选项是允许类卸载:

-XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

但是,这会使垃圾收集变得更慢,因此不适合高负载系统(并且不适用于 Java 7 及更高版本)。

如果您在 JBoss(或任何其他应用服务器)中执行重复的“热部署”,请尽量避免这种情况并改为冷部署(如果可能)。如果不是,那显然不是问题的原因。

如果您确实有泄漏问题,最好的选择是找出原因并解决它。使用 jmap 之类的工具,让您了解可能导致问题的候选人:

jmap -permstat <pid>

文档:http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html

另见这个问题:How to dump Permgen?

最后,考虑升级到 Java 8,因为它取消了 PermGen 空间的概念。相反,数据将成为堆的一部分(例如内部字符串)或称为 Metaspace 的新区域 - 默认情况下会被垃圾收集。

【讨论】:

permGen空间的增加并没有改变什么;我有同样的错误(内存不足)。我也使用了这些选项(-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled ),但不幸的是,结果是一样的。我已经使用 Java Visual VM、jmap、jhat 来查找内存泄漏的原因,但目前还没有结果。这很奇怪,因为有时我没有例外 您需要使用 CMS 垃圾收集器才能使这些选项生效。请参阅有关该内容和 Java 8 的更新。

以上是关于JFreeChart - Java 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

内存泄漏与垃圾回收机制

分析 ThreadLocal 内存泄漏问题

内存泄漏和内存溢出的区别

Android开发常见的Activity中内存泄漏及解决办法

OpenGL VBO 会泄漏内存吗?

PowerPoint 2010 内存泄漏?