NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
Hi Doug- Whoa! That's some leak. Doug Lindholm wrote:
A few months back I reported a problem I was seeing with running out of memory. It has now escalated to become a show-stopping problem. I've been doing some profiling to see where the resources are going. I've attached a simple sample program that demonstrates one such case. I make a Display, add a ScalarMap to it, then repeatedly setRange. When using a DisplayImplJ3D the instance count of Object[] and many java3d classes continues to grow. There is no such problem with the DisplayImplJ2D. I know very little about java3d. I'm hoping there is something VisAD can do to free up java3d resources and that this is not a java3d bug that we have no control over. Any ideas?
I modified your test slightly to add the display to a frame. When I did this, my total memory useage stayed around 7 Mb and I could see garbage collection running. If I don't add the display to a frame, memory use shoots through the roof. I've attached the revised program and a small memory monitor program. If you pass in a parameter to the MemoryTest, it will show the display, otherwise, just the monitor. I don't have time to track down the cause, but maybe this will help Tom Rink or one of the other developers. Thanks for the test program. Don ************************************************************* Don Murray UCAR Unidata Program dmurray@xxxxxxxxxxxxxxxx P.O. Box 3000 (303) 497-8628 Boulder, CO 80307 http://www.unidata.ucar.edu/staff/donm *************************************************************
import visad.*; import visad.java2d.*; import visad.java3d.*; import javax.swing.*; import java.awt.event.*; public class MemoryTest { public void init(boolean showDisplay) { try { //System.out.println("make display"); //DisplayImplJ2D display = new DisplayImplJ2D( "test" ); DisplayImplJ3D display = new DisplayImplJ3D( "test" ); //DisplayImplJ3D display = new DisplayImplJ3D( "test", new TwoDDisplayRendererJ3D() ); //System.out.println("make map"); ScalarMap xmap = new ScalarMap( RealType.Time, Display.XAxis ); //System.out.println("add map"); display.addMap(xmap); JFrame frame = new JFrame("Memory Test"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); if (showDisplay) frame.getContentPane().add(display.getComponent()); frame.getContentPane().add("South", new MemoryMonitor()); frame.pack(); frame.show(); int count = 0; while ( true ) { double now = (double) (System.currentTimeMillis() / 1000.0); // System.out.println("step " + count++ + " now = " + now ); double then = now - 3600.0; xmap.setRange(then, now); //Thread.sleep(10); } } catch (Throwable t) { t.printStackTrace(); } } public static void main(String[] args) { MemoryTest test = new MemoryTest(); test.init(args.length > 0); } }
// $Id: MemoryMonitor.java,v 1.4 2002/05/03 13:54:42 dmurray Exp $ /* * Copyright 1997-2000 Unidata Program Center/University Corporation for * Atmospheric Research, P.O. Box 3000, Boulder, CO 80307, * support@xxxxxxxxxxxxxxxx. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import javax.swing.*; import java.text.DecimalFormat; public class MemoryMonitor extends JPanel implements Runnable { boolean running = false; long sleepInterval = 2000; Thread thread; int percentThreshold = 80; int timesAboveThreshold = 0; static DecimalFormat fmt = new DecimalFormat("#0.00 MB"); JLabel label1 = new JLabel (""); JLabel label2 = new JLabel (""); Color labelForeground; public MemoryMonitor () { setLayout (new FlowLayout (FlowLayout.LEFT)); setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); add(label1); add(label2); //GuiUtils.hbox (this, Misc.newList (label1, label2)); MouseListener ml = new MouseAdapter () { public void mouseClicked (MouseEvent e) { if (running) stop (); else start (); } }; labelForeground = label2.getForeground (); label1.addMouseListener (ml); label2.addMouseListener (ml); start (); } private synchronized void stop () { running = false; label1.setEnabled (false); label2.setEnabled (false); } private synchronized void start () { if (running) return; label1.setEnabled (true); label2.setEnabled (true); running = true; thread = new Thread ( this, "Memory monitor"); thread.start (); } private void showStats () { double totalMemory = (double) Runtime.getRuntime ().totalMemory (); double freeMemory = (double) Runtime.getRuntime ().freeMemory (); double usedMemory = (totalMemory-freeMemory); int percent = (int)(100.0*(usedMemory/totalMemory)); totalMemory = totalMemory/1000000.0; usedMemory = usedMemory/1000000.0; label1.setText ("Memory usage: total: " + fmt.format (totalMemory) + " used: " + fmt.format (usedMemory)); label2.setText (" (" + percent +"%)"); // doing this continually slows things down //Runtime.getRuntime ().gc (); if (percent > percentThreshold) { timesAboveThreshold ++; if (timesAboveThreshold > 5) label2.setForeground (Color.red); Runtime.getRuntime ().gc (); } else { label2.setForeground (labelForeground); timesAboveThreshold = 0; } } public void run () { while (running) { showStats (); try {thread.sleep (sleepInterval);} catch (Exception exc) {} } } public void setRunning (boolean r) { running = r; } public boolean getRunning () { return running; } public static void main (String[]args) { JFrame f = new JFrame (); MemoryMonitor mm = new MemoryMonitor (); f.getContentPane ().add (mm); f.pack (); f.show (); } }
visad
archives: