Name: rm29839 Date: 07/13/98
Chained objects are not GC'ed in all JDK1.1.x on Solaris 2.x.
This bug is shown in JavaSoft's VM for Solaris2.x.
This bug is not shown in following VMs.
SunSoft's JDK 1.1.x for Solaris.
JavaSoft's JDK 1.1.x for Windows.
Linux JDK 1.1.6.
MRJ2.0
A evaluatable program is contained in this bug report.
Key point is following.
A Token object has a reference of next token.
Parser object has current Token reference.
token = token.next = getNextToken();
This statement sets next Token object
to `next' field of current Token object.
But reference of current Token object are changed
to next token.
At this time, the current token object are not refered from any objects.
So this object becomes target of GC.
But in all JDK1.1.x(1-6) of Solaris, OutOfMemoryError is occured.
(both green thread and native thread.)
Please run the program.
% java Parser
And please check memory size of the running java
using `ps -ef | grep java'.
You can also see growth of memory size.
Please run this program two or three time.
Timing of OutOfMemoryError is different every time.
In JDK 1.2beta4, OutOfMemoryError is not occurred.
But memory size is growing.
In SunSoft's JDK for Solaris,
this bug is not occurred.
Memory size is not growing.
So this fact becomes a hint to solve this bug.
In Linux JDK, JavaSoft's JDK1.1.x for Windows, and Apple's MRJ,
this bug is not occured.
Parser program has `-noChain' and `-gc' options.
% java Parser -noChain
At `noChain' option, Token objects are not chained.
token = getNextToken();
With this option, this bug is not occurred
in JavaSoft's JDK1.1.x for Solaris.
No memory size growth.
This is a key point.
% java Parser -gc
This option call System.gc per 1000 loop count.
With this option, Parser can live longer time.
But OutOfMemoryError is occurred.
Following is the test program `Parser.java'.
(I found this bug when I use my program generated by JavaCC.)
public class Parser {
Token token;
static boolean gc = false;
static boolean noChain = false;
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-gc")) {
gc = true;
} else if (args[i].equals("-noChain")) {
noChain = true;
}
}
Parser parser = new Parser();
parser.start();
System.out.println("Ok.");
}
public void start() {
token = getNextToken();
for (int i = 0; i < 1000000; i++) {
if (!noChain) {
token = token.next = getNextToken();
} else {
token = getNextToken();
}
if (i % 1000 == 0) {
System.out.println("i = "+i);
if (gc) {
System.gc();
System.out.println("gc done.");
}
}
}
}
Token getNextToken() {
Token newToken = new Token();
newToken.data = new char[1000];
return newToken;
}
class Token {
char[] data;
Token next;
}
}
(Review ID: 34866)
======================================================================