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.

Re: Resource Leak

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 ();
    }


}
  • 2002 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the visad archives: