Does Java accuse wrong memory usage values or is there something wrong with the algorithm?

6

I was studying GC and the question came up when I rode the below:

public class Garbage
{

    public static long carregarMemoria()
    {
        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 100000; i++)
        {
            list.add(i);
        }

        return Runtime.getRuntime().freeMemory();
    }

    public static void main(String[] args)
    {
        Runtime rt = Runtime.getRuntime();

        int MB = 1_048_576; //Bytes em um MB;

        long total = rt.maxMemory() / MB;

        long memUtil = total - carregarMemoria() / MB;

        System.out.println("Mem. total: " + total + "MB");

        System.out.println("Mem. util após sobrecarga: " + memUtil + "MB");

        rt.runFinalization();
        rt.gc();

        memUtil = total - rt.freeMemory() / MB;

        System.out.println("Mem. util após gc: " + memUtil + "MB");
    }

}

Output:

  

Mem. total: 1808MB

     

Mem. useful after overhead: 1690MB

     

Mem. useful after gc: 1686MB

1686 MB is a considerable memory for a program so simple, I checked the task manager and it does not accuse an abrupt use of memory. I'm using Eclipse and the manager says it uses 430MB, when I squeeze the code there is an extra ~ 15MB.

Is there something wrong with the code? Why can not I see this memory usage in the task manager?

    
asked by anonymous 19.10.2016 / 15:52

1 answer

7

The task manager is not trusted to see how much memory is being used. Also, you have to understand what each number really means. Consumption is often a bit misleading. There is a difference between reserved and actually used memory, just to name the main one.

There is nothing wrong with the code. You have just discovered that Java is memory-devouring. I talk about this in Why does Java consume so much memory? . I will not repeat here what is already there. There is a lot that occupies the memory even though not using.

This example

You have a specific consumption in an array with 100,000 Integer . If it is 32 bits only from the pointers to the integers they are already 400KB only occupied by the array . If it is 64 bits, it goes up to 800KB.

Then you have the instances. I do not know how much Java is currently consuming, but it looks like it had an overhead of 16 bytes of the object, if it is 32 bits. More, at least, 4 bytes of the value itself. So at least 20 bytes times 100 thousand, it gives 2MB. At 64 bits it would be 3.6MB (note that the numbers may not be exactly these, but gives a basis as it occupies very proportionally).

It's a lot and it's little depending on how you see it. It is little in total. But if you consider that C, C ++, C # and other languages will occupy only 400KB independent of the architecture, it's a lot.

Garbage Collector

Another detail is that under normal conditions should not call gc() . I understand that for testing okay, but not always he will do what he expects. I talk about this in a few questions:

19.10.2016 / 16:15