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

Asked

Viewed 93 times

8

I was studying GC and the doubt arose when I ran it 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");
    }

}

Exit:

Mem. total: 1808MB

Mem. util after overload: 1690MB

Mem. util after gc: 1686MB

1686 MB is a considerable memory for such a simple program, I checked in the task manager and it does not show abrupt memory usage. I am using Eclipse and the manager says that it uses 430MB, when I run the code there is an extra ~15MB.

Is there something wrong with the code? Because I can’t see this memory usage in the task manager?

1 answer

8


The task manager is unreliable to see how much memory is being used. In addition it is necessary to understand what each number actually means. Consumption is often a little misleading. There is difference between memory reserved and effectively used, only to quote the main.

There’s nothing wrong with the code. You just found out that Java is memory-eating. I talk about it in Why Java consumes so much memory?. I will not repeat here what is already there. There is a lot that occupies the memory even if not using.

That example

Has a specific consumption in a array with 100,000 Integer. If it is 32 bits pointer only for integers it is already 400KB occupied only by array. If it’s 64 bits, it goes up to 800KB.

Then there are the instances. I don’t know how much Java is currently consuming, but it seems that it had a overhead 16 bytes of the object, if it is 32 bits. Plus at least 4 bytes of the value itself. Then at least 20 bytes times 100 thousand, gives 2MB. In 64 bits it would be 3.6MB (note that the numbers may not be exactly these, but gives a basis as occupies very proportionally).

It’s too much or it’s too little depending on how you see it. It’s too little in total. But if you consider that C, C++, C# and other languages will only occupy 400KB independent of architecture, it’s very.

Garbage Collector

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.