Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4065018

(gc) Require heap compaction (return memory to OS)

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.1.7
    • 1.1.3, 1.1.4, 1.1.5, 1.2.0
    • hotspot
    • b04
    • generic, x86, sparc
    • solaris_2.5.1, solaris_2.6, windows_95, windows_nt

        Name: rlT66838 Date: 07/16/97

        Our application is designed to remain running for long periods of
        time, and the current JVM implementation (where memory is
        garbage-collected back to the heap, but never released from the
        heap back to the OS) is *killing* us.


        ======================================================================

        "I have written a test app which creates some number of objects on a
        button click. When run with '-verbosegc', I see the output where the gc
        is telling me it's doing its thing and compacted x bytes. Yet, no matter
        how many times I click my app, I never see any change in the mem usage in
        Task Manager (NT 4.0). In this trivial test app, it's hard to see
        profound problems. What's a few K of memory between friends? But in our
        real-life app, it's virtually impossible to run it for more than a few
        hours without getting an out of mem exception. [That is, before we
        created an object recycler and reuse absolutely every object we create.]
        And, since this is a mission critical app, that kinda sucks.

        "I'm aware (and have used) the flag to set the max heap size. That's not
        the problem. If I run the VM with the '-verbosegc' flag, I can watch the
        garbage collector run, but neither the VM's mem usage or VM Size change in
        Task Mgr. Ever. I've run numerous test cases and have only seen those
        values increase, never decrease. Well, that's not exactly true - they
        both decrease if you minimize the window(!). I don't understand that but
        it might help diagnose the problem.

        "I'm quite certain this is not a result of memory leaks because the
        '-verbosegc' output clearly says memory was compacted on the heap.

        This customer is using JDK 1.1.4 (they looked at 1.1.5 and the problem
        persists).


        import java.awt.*;
        import java.awt.event.*;

        /*

          This little app simply allocates some stuff when it's button is pressed.

          This demonstrates the VM bug where objects are garbage collected but that
          memory is never returned to the OS (this has only been tested on NT 4.0).

          You can clearly see this by running the VM with -verbosegc
          (java -verbosegc -classpath .;\java\lib\classes.zip MemTestApp).

        */

        public class MemTestApp {

          public static void main(String[] args) {
            MemTestFrame memTestFrame = new MemTestFrame();
            Dimension dim = new Dimension(300,300);
            memTestFrame.setSize(300,300 /*dim*/);
            memTestFrame.init();
            memTestFrame.show();
          }

        }

        class MemTestFrame extends Frame implements ActionListener {

          private Font font = null;
          private Button button;
          private String message = "Mem Test";

          public void init() {
            setTitle(message);
            setVisible(true);
            button = new Button();
            add(button);
            button.setLabel("Click to alloc 500 objects...");
            button.addActionListener(this);
          }

          public void actionPerformed(ActionEvent evt) {
            System.out.println("------> allocing 500 objects...");
            MemObj obj;
            for (int i = 0; i < 50; i++)
              obj = new MemObj();
            System.out.println("------> done.");
          }

        }

        class MemObj {
          Font font;
          Rectangle rect;
          java.math.BigDecimal number;


          public MemObj() {
            font = new Font("Dialog", Font.PLAIN, 16);
            rect = new Rectangle(0,0,50,50);
          }
        }


        janet.koenig@Eng 1998-01-13

        Response to request for test case:

        Any java program shows this behaviour. If memory is allocated by the
        virtual machine from the operating system it is never returned to the
        operating system until the process exits. Compare this to Microsoft's VM
        behaviour where its size is directly related to how many objects are live
        in the system.

        Another response:

        IMHO, the problem is that the VM is allowed to expand the heap (and it
        should), but that it does not contract. Of course, it should be
        reluctant to do either, and I have seen that it takes a good while to
        decide to go get more memory...

        Anyway, with the current memory model, the EFFECTIVE working set size
        of a java app is the same as its virtual space (sigh, hard to be
        worse). This is not a problem for toys, but for SERVER applications,
        this can be a problem. My application grows to over 80MB. As you
        might imagine, SERIOUS thrashing occurs.

        If, at an appropriate time, memory were compacted and "excess"
        returned to the OS, the working set size would be reduced.

        Of course, other garbage techniques (like generational) would help a
        great deal too.

              never Tom Rodriguez
              rlewis Roger Lewis (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: