Trying to understand GC with below piece of code

public class Test1 {
    public static void main(String[] args) {

        //HashMap<String,String> newmap = new HashMap<String,String>();
        //CleanUpThread t = new CleanUpThread(newmap);
        ArrayList<Double> al = new ArrayList<Double>();
        //t.start();
        while(true){

            al.add(Math.random());


            try {
                Thread.currentThread().sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }


    }
}

Since am creating random double objects into a list , i am expecting out of memory error to occur and my heap get filled.

But i see My GC being cleaning up and only ~1Mb of data stays in survivor space.

Running the jvm with 32MB heap size and occupancy % for GC set to 30%.

Can anyone give more explanation on the behavior.enter image description here

2 Answers

3
Golov Pavel On

First of all, you didn't appear OutOfMemoryError, becouse objects in your code are created very slow (every 200 ms). Try to remove sleep fragment of code.

Secondly, if your GC cleaned data in the survivor space, it doesn't mean that GC remove this objects from the memory. It means, that GC moved these objects to the Old generation, because they survived several garbage collections. You can see, that the size of the Old Generation only grow and no garbage collections happened there.

enter image description here

When your heap size will be filled, GC will try to clean up objects (you will see the often fluctuations on the GC time chart), but this attempts will be unsuccessful, because it will no objects to delete. Over time, you will receive OME.

I think that if you remove sleep fragment of code and wait enough time you will receive OME.

For faster results you can reduce the heap size.

0
Community On

whenever you Eden space is filled, Minor GC runs and it transfers the alive objects to the survivor. After some iteration, the long-lived survivor objects are transferred to the old Generation space.

In your case, minor GC is running whenever the Eden space is exhausted to a percentage and the Old generation size is increasing with time. you can figure this in the graph.

Remove the sleep interval, it will give you a more clear view. Also, you can configure the heap size to analyze better.

For more understanding, you can refer https://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java