Status: New
Owner: ----

New issue 74 by jfuerth: Memory leak with PSwingRepaintManager

What steps will reproduce the problem?
1. Create and display a PSwingCanvas on a panel in an application.
2. Move to a different part of the application where the panel is no longer
visible and should be garbage collected.

What is the expected output? What do you see instead?
I am expecting the PSwingCanvas and the panel it is on to be eligible for
garbage collection. However, analysis of the Java heap shows the panel and
PSwingCanvas are still reachable from the root set via the
PSwingRepaintManager singleton referenced from the static
PSwingCanvas.pSwingRepaintManager field. (this is more noticable if the
panel also contains a JTable with 70,000 rows!)

The PSwingRepaintManager is a singleton and it accumulates references to
all PSwingCanvas instances that have ever been painted. This causes the
entire component tree rooted at every PSwingCanvas to not be eligible for
garbage collection.

The simplest and most reliable way to fix this problem would be to keep
weak references to the PSwingCanvases so the singleton on its own can't
keep them alive.

The following patch implements this suggestion and it has been shown to  

### Eclipse Workspace Patch 1.0
#P piccolo2d
(revision 425)
(working copy)
@@ -32,8 +32,8 @@

  import javax.swing.*;
  import java.awt.*;
-import java.util.ArrayList;
  import java.util.Vector;
+import java.util.WeakHashMap;

   * This RepaintManager replaces the default Swing implementation, and is
used to
@@ -70,7 +70,12 @@
   * @author Sam R. Reid
  public class PSwingRepaintManager extends RepaintManager {
-    private ArrayList swingWrappers = new ArrayList();
+       /**
+        * All keys in this map are weak references to swing wrappers. The 
+        * are all null!
+        */
+    private final WeakHashMap swingWrappers = new WeakHashMap();

      // The components that are currently painting
      // This needs to be a vector for thread safety
@@ -131,7 +136,7 @@
          // need to translate the repaint request since the component may
          // be offset inside another component.
          for (Component comp = c; comp != null && comp.isLightweight() &&
!captureRepaint; comp = comp.getParent()) {
-            if (swingWrappers.contains(comp.getParent())) {
+            if (swingWrappers.containsKey(comp.getParent())) {
                  if (comp instanceof JComponent) {
                      captureRepaint = true;
                      capturedComponent = (JComponent) comp;
@@ -197,6 +202,6 @@

      void addPSwingCanvas(PSwingCanvas swingWrapper) {
-        swingWrappers.add(swingWrapper.getSwingWrapper());
+        swingWrappers.put(swingWrapper.getSwingWrapper(), null);
\ No newline at end of file

You received this message because you are listed in the owner
or CC fields of this issue, or because you starred this issue.
You may adjust your issue notification preferences at:

Piccolo2D Developers Group:

Reply via email to