Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2016090 | 1.2.0 | Tom Rodriguez | P3 | Closed | Fixed | 1.2beta4 |
JDK-2016089 | 1.1.8 | Tom Rodriguez | P3 | Closed | Fixed | 1.1.8 |
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.
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.
- backported by
-
JDK-2016089 (gc) Require heap compaction (return memory to OS)
- Closed
-
JDK-2016090 (gc) Require heap compaction (return memory to OS)
- Closed
- relates to
-
JDK-4205305 (1.1) Performance problem due to GC heap compaction fix (4065018)
- Closed
-
JDK-4158673 Garbage Collection Algorithm Flaws
- Closed