Hi Les, UBA-1053 has been fixed in ULC 6.0. The problem was that parent window was holding on to child windows in its ownedWindow data structure even after child windows were disposed. See the snippet below for verification. Run the GC after you have closed the dialogs.
The figures you are getting in your example are misleading because there is no guarantee when the garbage collector will run. The closed dialogs will be collected only when the GC runs. So, you should force the GC to run (as shown in the snippet I have enclosed. BTW, where are you encountering memory leak and OutOfMemoryError? On the client or on the server? Did you run the profiler? Thanks and regards, Janak -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Les Thomas Sent: Friday, January 26, 2007 5:11 PM To: [EMAIL PROTECTED] Subject: [ULC-developer] ULCMemory Leak - Support Request Hi, Please feel free to treat this as support request. We believe we are experiencing a fairly significant memory lead using a ULCDialog (with a client-side extension). Our application is fairly complex, and before we start to diagnose the problem, I would like to confirm that bug UBA 1053- "Memory leak for ULCDialogs that have an owner (i.e. a parent window)" has in fact been fixed. When I run a simple test, I notice that there still appears to be a leak. The dialog used in the test uses ULCDialog.DISPOSE_ON_CLOSE and has a ULCFrame as its owner. This is similar to our application. When I run the sample program below, which I used from a similar email : http://lists.canoo.com/mailman/private/ulc-developer/2005/002598.html, the application doesn't appear to release all memory. For example: Before: Total - 4232KB Used - 3981.03 After 50 dialog objects created - Total - 5776KB Used - 4303KB After 50 dialog objects disposed - - 5776KB Used - 5731KB Any tips or hints would be appreciated. Kind regards, Les Sample program: import com.ulcjava.base.application.AbstractApplication; import com.ulcjava.base.application.*; import com.ulcjava.base.application.event.IActionListener; import com.ulcjava.base.development.DevelopmentRunner; import com.ulcjava.base.application.event.ActionEvent; public class Example extends AbstractApplication { public void start() { final ULCFrame mainFrame = new ULCFrame("MemoryTestApplication"); mainFrame.setSize(600, 400); mainFrame.setDefaultCloseOperation(com.ulcjava.base.application. ULCFrame.TERMINATE_ON_CLOSE); ULCBoxPane layoutPane = new ULCBoxPane(); mainFrame.add(layoutPane); ULCButton button = new ULCButton("open dialog"); layoutPane.add(button); button.addActionListener(new IActionListener() { public void actionPerformed(ActionEvent event) { System.out.println(">>>>> Dialog free memory: " + Runtime.getRuntime().freeMemory() + " / max " + Runtime.getRuntime().maxMemory()); ULCDialog dialog = new ULCDialog(mainFrame, "Test", false); dialog.setDefaultCloseOperation(ULCDialog.DISPOSE_ON_CLOSE); dialog.add(new ULCTree()); dialog.setVisible(true); }; }); ULCButton memoryButton = new ULCButton("Display Memory"); memoryButton.addActionListener(new IActionListener() { public void actionPerformed(ActionEvent event) { System.out.println(">>>>> Memory - free memory: " + Runtime.getRuntime().freeMemory() + " / max " + Runtime.getRuntime().maxMemory()); }; }); layoutPane.add(memoryButton); mainFrame.setVisible(true); } public static void main(String[] args) { DevelopmentRunner.setApplicationClass(Example.class); DevelopmentRunner.main(args); } } ------------------ import com.ulcjava.base.application.AbstractAction; import com.ulcjava.base.application.AbstractApplication; import com.ulcjava.base.application.ULCBoxPane; import com.ulcjava.base.application.ULCButton; import com.ulcjava.base.application.ULCComponent; import com.ulcjava.base.application.ULCDialog; import com.ulcjava.base.application.ULCFrame; import com.ulcjava.base.application.ULCWindow; import com.ulcjava.base.application.UlcUtilities; import com.ulcjava.base.application.event.ActionEvent; import com.ulcjava.base.development.DevelopmentRunner; public class PR1053 extends AbstractApplication { public void start() { ULCFrame frame = new ULCFrame("PR1053"); ULCBoxPane contentPane = new ULCBoxPane(1, 0); contentPane.add(new ULCButton(new ListOwnedWindowsAction(frame))); contentPane.add(new ULCButton(new OpenDialogAction())); contentPane.add(new ULCButton(new RunGCAction())); frame.setDefaultCloseOperation(ULCFrame.TERMINATE_ON_CLOSE); frame.getContentPane().add(contentPane); frame.setVisible(true); } private static class ListOwnedWindowsAction extends AbstractAction { private ULCFrame fFrame; public ListOwnedWindowsAction(ULCFrame parentFrame) { fFrame = parentFrame; putValue(NAME, "List owned dialogs"); } public void actionPerformed(ActionEvent event) { ULCWindow[] ownedWindows = fFrame.getOwnedWindows(); for (int i = 0; i < ownedWindows.length; i++) { ULCWindow ownedWindow = ownedWindows[i]; System.out.println(ownedWindow); } System.out.println("---"); } } private static class OpenDialogAction extends AbstractAction { public OpenDialogAction() { putValue(NAME, "Open Dialog"); } public void actionPerformed(ActionEvent event) { System.out.println(">>>>> memory before Dialog visible: " + Runtime.getRuntime().freeMemory() + " / " + Runtime.getRuntime().maxMemory()); ULCDialog dialog = new ULCDialog(UlcUtilities.getWindowAncestor((ULCComponent)event.getSource()), "Dialog", false) { protected void finalize() throws Throwable { System.out.println("PR1053.finalize"); } }; dialog.setDefaultCloseOperation(ULCDialog.DISPOSE_ON_CLOSE); dialog.setSize(400, 300); dialog.setVisible(true); } } private static class RunGCAction extends AbstractAction { public RunGCAction() { putValue(NAME, "Run GC"); } public void actionPerformed(ActionEvent event) { System.out.println(">>>>> memory before GC: " + Runtime.getRuntime().freeMemory() + " / " + Runtime.getRuntime().maxMemory()); Runtime.getRuntime().gc(); Runtime.getRuntime().runFinalization(); System.out.println(">>>>> memory after GC: " + Runtime.getRuntime().freeMemory() + " / " + Runtime.getRuntime().maxMemory()); } } public static void main(String[] args) { DevelopmentRunner.setApplicationClass(PR1053.class); DevelopmentRunner.main(args); } } _______________________________________________ ULC-developer mailing list [email protected] http://lists.canoo.com/mailman/listinfo/ulc-developer
