Dear Java programmers,
Can anyone tell me why I am getting an out-of-memory error with the
code below?
I am using a 'swapable' object (SObject), whose instance variable (an
'int') is buried inside an inner 'Rep' class. The extra level of
indirection allows the call x.swap(y) to exchange the integer values
of x and y. The container class (SArray) has a method that allows a
swapable object to exchange integer values with an object inside the
container. For example, s.swapAt(x, i) will cause the integer value
of x to be exchanged with the object at location i in s.
The program shown below uses a for-loop to populate the SArray with
one million SObjects. It does this using the 'insert' method which is
implemented with assignment. The next for-loop overwrites those one
million objects with new objects. This produces a million memory
leaks, but the garbage collector handles them. The final for-loop
'swaps' one million new objects with the million objects put there by
the second loop. This is where the program runs out of memory. So I
get the following output:
Done with initial input
Done with assignment overwrite
Exception in thread "main" java.lang.OutOfMemoryError
I was under the impression the the garbage collector kicked in when
memory was low and cleaned things up. At any given time during the
third loop there are only a little over a million objects in memory
that are accessible - everything else it garbage. So wouldn't the
garbage collector be able to reclaim the memory from these leaks? I
expect the third loop to take more time because of the extra garbage,
but I do not understand why the program would run out of memory.
Any information on why this is occuring or how it might be prevented
would be helpful.
Greg K.
package swaptest;
public class Main {
private static final int MAX = 1000000;
public static void main(String[] args) {
SArray s = new SArray(MAX);
for (int i = 0; i < MAX; i++) { s.insertAt(new SObject(), i); }
System.out.println("Done with initial input");
for (int i = 0; i < MAX; i++) { s.insertAt(new SObject(), i); }
System.out.println("Done with assignment overwrite");
for (int i = 0; i < MAX; i++) { s.swapAt(new SObject(), i); }
System.out.println("Done with swapping overwrite");
}
}
package swaptest;
public class SArray {
private SObject[] contents;
public SArray(int max) { contents = new SObject[max]; }
public void swapAt(SObject x, int i) { contents[i].swap(x); }
public void insertAt(SObject x, int i) { contents[i] = x; }
}
package swaptest;
public class SObject {
public class Rep { public int n; }
public Rep rep = new Rep();
public SObject() { rep.n = 0; }
public void swap(SObject x) {
Rep temp = rep;
rep = x.rep;
x.rep = temp;
}
}