I had read an article long back and I dont seem to find it. It explained the below behavior where an object in scope might still not be cleared. In any case can you please help explain on why the below ends in OutOfMemoryError
public static void main(String[] args) {
List<A> collect = null;
int i=0;
while(true){
System.out.println(i++);
collect = IntStream.range(0, 10_00_000).mapToObj(x -> new A(x + "")).collect(Collectors.toList());
}
}
class A{
String temp;
A(String a){
this.temp = a;
}
}
When I put a finalize
in A
with a print statement, it is never printed. And the instance ends with OOME
after few iterations. Why isn't gc
clearing previously created collect
. And the number of iterations as well is not constant, it ranges from 3
to even 100
but ultimately fails for -Xmx500m
Secondly for fun, I ran the above program with JIT disabled -Djava.compiler=NONE
. And it runs forever as expected. How is JIT influencing it?
PS: When In include a System.gc();
inside my while clause, it keeps running as expected.
I can’t reproduce your result with -Xmx500m
, but with -Xmx200m
. Consistently, the program will fail when you add the finalize()
method, as the finalizer is the cause of the problem. However, there are some "finalized"
message printed in my system. Without the finalize()
method, it runs perfectly forever (well, actually until I kill it).
There is no problem reclaiming the space of ordinary objects, but when you add a nontrivial finalize()
method, you are actively preventing the objects from going out of scope, as they now must be enqueued for finalization.
While the JVM will always perform a garbage collection, trying to free all unused objects, before throwing an OutOfMemoryError
, there is no such guaranty for objects hanging in the finalization queue. Slowing down the main task by disabling the JIT may indeed allow the finalization to process more elements. Keep in mind that having both, the main task and the finalize method printing to System.out
has a synchronization effect which can make the timing of the processing critical.
The are several environmental aspects that can influence the outcome. Since there is no guaranty regarding which thread will execute a finalizer, the finalization can use all unused CPU cores (and your main thread uses only one). Also the actual garbage collection algorithm (the JVM allows selecting one of several different algorithms) can have an impact.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With