Hi All,
1. Sometimes, you need to refresh the chart, so JFreeChart.fireChartChanged() should be public, instead of protected.
So it would be easy to call from outside.
2. OverlaidXYPlot.subplots should be protected, not private. Or add a method
List getSubplots().
Sometimes, you need to insert or remove sub plots.
3. This will be a major one: most of objects can not be garbage collected,
because most of them are cross referenced. For example, in JFreechart
there is a Plot, the plot holds a reference to JFreechart as a listnerer.
Garbage Collector only collects the objects who do not have outstanding
reference. But JFreeChart and Plot reference each other. The current
design uses a lot of listeners, allmost all of them cross referenced.
Of course, there are out side listneres which reference back. That
would be "secondary": the user does have some responsibility for that.
I have spend three whole day to play with that. I have tried to add a
method JFreeChart.dispose and made some progress,
but it is too deep and I gave up. This issue should be addessed at
architecture level.
Thanks.
feature request
Re: feature request
Wei Jiang wrote:
> 1. Sometimes, you need to refresh the chart, so
> JFreeChart.fireChartChanged() should be public, instead of
> protected.
> So it would be easy to call from outside.
You are probably right. But can you give me an example of when you require this, so I can just check that it wouldn't be better to handle it some other way.
> 2. OverlaidXYPlot.subplots should be protected, not private.
> Or add a method
> List getSubplots().
> Sometimes, you need to insert or remove sub plots.
There is a method to add a subplot, but I need to add one to remove a subplot.
> 3. This will be a major one: most of objects can not be
> garbage collected,
> because most of them are cross referenced. For example, in
> JFreechart
> there is a Plot, the plot holds a reference to JFreechart as
> a listnerer.
> Garbage Collector only collects the objects who do not have
> outstanding
> reference. But JFreeChart and Plot reference each other. The
> current
> design uses a lot of listeners, allmost all of them cross
> referenced.
My understanding of the garbage collector (which may be incorrect) is that it looks for objects that are "unreachable". Just because A references B (and possibly B references A) doesn't mean that A and B won't be removed by the garbage collector. I think if neither A nor B can be reached, then they are subject to removal.
That said, if you can supply a sample program that demonstrates a memory "leakage" caused by holding onto references unnecessarily, I'll certainly try to hunt down the problem...
Regards,
Dave Gilbert
> 1. Sometimes, you need to refresh the chart, so
> JFreeChart.fireChartChanged() should be public, instead of
> protected.
> So it would be easy to call from outside.
You are probably right. But can you give me an example of when you require this, so I can just check that it wouldn't be better to handle it some other way.
> 2. OverlaidXYPlot.subplots should be protected, not private.
> Or add a method
> List getSubplots().
> Sometimes, you need to insert or remove sub plots.
There is a method to add a subplot, but I need to add one to remove a subplot.
> 3. This will be a major one: most of objects can not be
> garbage collected,
> because most of them are cross referenced. For example, in
> JFreechart
> there is a Plot, the plot holds a reference to JFreechart as
> a listnerer.
> Garbage Collector only collects the objects who do not have
> outstanding
> reference. But JFreeChart and Plot reference each other. The
> current
> design uses a lot of listeners, allmost all of them cross
> referenced.
My understanding of the garbage collector (which may be incorrect) is that it looks for objects that are "unreachable". Just because A references B (and possibly B references A) doesn't mean that A and B won't be removed by the garbage collector. I think if neither A nor B can be reached, then they are subject to removal.
That said, if you can supply a sample program that demonstrates a memory "leakage" caused by holding onto references unnecessarily, I'll certainly try to hunt down the problem...
Regards,
Dave Gilbert
Re: feature request
>> 1. Sometimes, you need to refresh the chart, so
>> JFreeChart.fireChartChanged() should be public, instead of
>> protected.
>> So it would be easy to call from outside.
>You are probably right. But can you give me an example of when you >require this, so I can just check that it wouldn't be better to handle it >some other way.
I use an OverlaidXYPlot for a dynamic dataset. When the data changes,
I need to redraw the chart. Maybe there is a better way to do so?
>> 2. OverlaidXYPlot.subplots should be protected, not private.
>> Or add a method
>> List getSubplots().
>> Sometimes, you need to insert or remove sub plots.
>There is a method to add a subplot, but I need to add one to remove a >subplot.
And an insert, clear... What if the user want to re-order sub plots?
By the way, OverlaidXYPlot shows sub plots not in ascending order. Is it
a bug? I use version 0.92
>That said, if you can supply a sample program that demonstrates a >memory "leakage" caused by holding onto references unnecessarily, I'll >certainly try to hunt down the problem...
I will try.
Thanks
>> JFreeChart.fireChartChanged() should be public, instead of
>> protected.
>> So it would be easy to call from outside.
>You are probably right. But can you give me an example of when you >require this, so I can just check that it wouldn't be better to handle it >some other way.
I use an OverlaidXYPlot for a dynamic dataset. When the data changes,
I need to redraw the chart. Maybe there is a better way to do so?
>> 2. OverlaidXYPlot.subplots should be protected, not private.
>> Or add a method
>> List getSubplots().
>> Sometimes, you need to insert or remove sub plots.
>There is a method to add a subplot, but I need to add one to remove a >subplot.
And an insert, clear... What if the user want to re-order sub plots?
By the way, OverlaidXYPlot shows sub plots not in ascending order. Is it
a bug? I use version 0.92
>That said, if you can supply a sample program that demonstrates a >memory "leakage" caused by holding onto references unnecessarily, I'll >certainly try to hunt down the problem...
I will try.
Thanks
Re: feature request
Here is the test program using version 0.94.
It runs from
going Wed Dec 11 08:57:29 EST 2002
to
going Wed Dec 11 08:58:25 EST 2002
and got error:
Exception in thread "main" java.lang.OutOfMemoryError
import java.util.*;
import com.jrefinery.chart.demo.*;
public class MemoryTest extends OverlaidXYPlotDemo {
public MemoryTest(String title) {
super(title);
}
public static void main(String[] argc) {
try {
while (true) {
MemoryTest demo = new MemoryTest("Overlaid XYPlot Demo");
demo.pack();
demo.setVisible(true);
System.out.println("going " + new Date());
demo.setVisible(false);
//Thread.currentThread().sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
It runs from
going Wed Dec 11 08:57:29 EST 2002
to
going Wed Dec 11 08:58:25 EST 2002
and got error:
Exception in thread "main" java.lang.OutOfMemoryError
import java.util.*;
import com.jrefinery.chart.demo.*;
public class MemoryTest extends OverlaidXYPlotDemo {
public MemoryTest(String title) {
super(title);
}
public static void main(String[] argc) {
try {
while (true) {
MemoryTest demo = new MemoryTest("Overlaid XYPlot Demo");
demo.pack();
demo.setVisible(true);
System.out.println("going " + new Date());
demo.setVisible(false);
//Thread.currentThread().sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Re: feature request
Your code creates many instances of the MemoryTest class (which is a subclass of a subclass of...a JFrame). The last thing you do with each instance of the JFrame is setVisible(false)...but that doesn't allow Swing to let go of the frame, so it never gets garbage collected. Below is an equivalent demo program that does not use JFreeChart at all, but still results in the out of memory problem. Uncomment the marked line and it should work better.
Regards,
DG
package memory;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.ImageIcon;
public class MemoryTest {
public static void main(String[] args) {
try {
while (true) {
JFrame demo = new JFrame("Test");
BufferedImage image = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
JPanel panel = new JPanel();
panel.add(new JButton(new ImageIcon(image)));
demo.setContentPane(panel);
demo.pack();
demo.setVisible(true);
long f = Runtime.getRuntime().freeMemory();
long t = Runtime.getRuntime().totalMemory();
System.out.println("Free memory: " + f + "/" + t);
demo.setVisible(false);
// demo.dispose(); *** UNCOMMENT THIS TO GET BETTER RESULTS ***
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
Regards,
DG
package memory;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.ImageIcon;
public class MemoryTest {
public static void main(String[] args) {
try {
while (true) {
JFrame demo = new JFrame("Test");
BufferedImage image = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
JPanel panel = new JPanel();
panel.add(new JButton(new ImageIcon(image)));
demo.setContentPane(panel);
demo.pack();
demo.setVisible(true);
long f = Runtime.getRuntime().freeMemory();
long t = Runtime.getRuntime().totalMemory();
System.out.println("Free memory: " + f + "/" + t);
demo.setVisible(false);
// demo.dispose(); *** UNCOMMENT THIS TO GET BETTER RESULTS ***
}
}
catch (Exception e) {
System.out.println(e);
}
}
}