Memory Management

How do you recover from out-of-memory without using more memory?



What is the proper way to check memory availability?


(Submitted by Michael L. Creech)
Some system memory information can be obtained from the lang.Runtime class.

Here is a little application that prints the free and total memory available. Note that the free memory number is only an estimate. I believe is may be more accurate if you run the garbage collector (gc()) before calling 'freeMemory()'.

import java.applet.*; // we use Applet
import java.awt.*;    // we use Graphics

public class MemoryStats
{
  public static void main (String args[])
    {

      Runtime rt    = Runtime.getRuntime ();
      rt.gc (); // Optional step to make memory numbers more accurate?
      long freeMem  = rt.freeMemory (); // Not always accurate; an estimate.
      long totalMem = rt.totalMemory ();

      System.out.println ("Total Memory Available = " + totalMem);
      System.out.println ("Free Memory Available  = " + freeMem);
    }
}
(Submitted by Steve Alexander)
Checking memory availability on a client system can be accomplished using the Runtime class which provides basic information about the VM environment of a particular user.

The sample application below uses several methods of the Runtime class (getRuntime(), freeMemory, totalMemory and the garbage collector (gc()) to display pre- and post-garbage collector information about the amount of memory available.

The Runtime class is static and therefore need not be explicitly instantiated.

import java.awt.*;
import java.lang.Thread;
import java.lang.Runtime;
import java.io.IOException;

public class ExecDemo extends Frame
{
        public String textString;
        Runtime rt;

        long freeMem, freeMem2, totalMem, totalMem2;

        public static void main(String args[])
        {
            ExecDemo m = new ExecDemo("Test");
            Button clearMem = new Button("Run Garbage Collector");
            m.add("South", clearMem);
            m.start();
        }

        public void start()
        {
            resize(400,125);
            rt = Runtime.getRuntime();
            show();

            freeMem = rt.freeMemory();
            totalMem = rt.totalMemory();
        }

        public ExecDemo(String s)
        {
            super("VM Memory Example");
        }

        public void paint(Graphics g)
        {
            g.drawString("Free memory (pre-GC) = ", 15, 20);
            g.drawString(Long.toString(freeMem), 150, 20);

            g.drawString("Total memory (pre-GC) =", 15, 35);
            g.drawString(Long.toString(totalMem), 150, 35);

            g.drawString("Free memory (post-GC) = ", 15, 50);
            g.drawString(Long.toString(freeMem2), 150, 50);

            g.drawString("Total memory (post-GC) =", 15, 65);
            g.drawString(Long.toString(totalMem2), 150, 65);

            g.setColor(Color.blue);
            g.drawString("All memory in bytes", 15, 80);
        }

        public boolean handleEvent(Event e)
        {
            if(e.target instanceof Button)
            {
                String label = ((Button)e.target).getLabel();
                if(label.equals("Run Garbage Collector"))
                {
                    //System.gc();
                    rt.gc();
                    freeMem2 = rt.freeMemory();
                    totalMem2 = rt.totalMemory();
                    repaint();
                    return true;
                }
            }
            return false;
        }
}

How do you allocate stack space and heap space for your application? Can these be dynamically changed? Can you define exceptions that enlarge them when necessary?



How do I know if my application design "outruns" the built-in garbage collection?