Testing the following code from a book

    public class RunTime {

        public static void main(String[] args) {

            Runtime r = Runtime.getRuntime();

            //MEMORY MANAGEMENT

            long mem1, mem2;


            Integer intmatrix[] = new Integer[1000];
            System.out.println("Total memory is :" + r.totalMemory());


            mem1 = r.freeMemory();
            System.out.println("Initial free memory is :" + mem1);

            r.gc();

            mem1 = r.freeMemory();
            System.out.println("free memory after garbage collection :" + mem1);

            for (int i = 0; i < 1000; i++) {
                intmatrix[i] = new Integer(i);
            }
                mem2 = r.freeMemory();
                System.out.println("free memory after integer allocation :" + mem2);
                System.out.println("memory used by allocation :" + (mem1 - mem2));

                for (int i = 0; i < 1000; i++) {
                    intmatrix[i] = null;
                }

                r.gc();
                mem2 = r.freeMemory();
                System.out.println("free memory after collecting discarded integers :" + mem2);


        }
    }

gives the following results :

Total memory is :16252928
Initial free memory is :15956728
free memory after garbage collection :16153296
free memory after integer allocation :15969624
memory used by allocation :183672
free memory after collecting discarded integers :16152840

183672 bytes for 1000 integers?

what you are doing is assuming the garbage collector will actually run.
it may, or may not.

but, do realise, that you also create an array, several String's, ...

anyway, all you can do is request the garbage collector to run, but in the end it's the JVM that will decide whether or not it'll run.

Also note that Integer is a class, so you are creating 1000 new instances of that class. That's not the same as 1000 ints (primitives) that would be just 4 bytes each

Also note that Integer is a class, so you are creating 1000 new instances of that class. That's not the same as 1000 ints (primitives) that would be just 4 bytes each

However, if you look at the class, the only non static member is an int, so, logically, it SHOULD only be 8 bytes, the object reference and the one member (and the object reference was already created by the creation of the array).

However, it probably never gets out of the young generation space and so there is probably a lot of "dead" space.

I believe that each and every instance has a minimum 8 byte fixed overhead and is aligned on an 8 byte boundary in the current Oracle JVMs (obviously this can and will vary with versions of the JVM). On that basis I would expect 16 bytes per instance.

Probably true. Not sure, was never ALL that interested. But, as I say, I believe the reason he sees about 180 per instance is simply because it never makes it out of young generation and so any "work" items from the for loop, etc, make up a bunch of "dead" space in the final "used" figure.

my view is that all Object exists untill main class is fully executed,

Total memory is :63438848
Initial free memory is :62778040
free memory after garbage collection :63155624
free memory after integer allocation :62494816
memory used by allocation :660808
free memory after collecting discarded integers :63165616

so different situations can be with code where this logics is executed from contructor

Total memory is :63438848
Initial free memory is :62778040
free memory after garbage collection :63155608
free memory after integer allocation :62494824
memory used by allocation :660784
free memory after collecting discarded integers :63165600

signal for GC is asynchronous, you have to wait for result, this is only on GC to decide when will be running and if run or not

Total memory is :63438848
Initial free memory is :62778040
Thread.sleep(2500)
free memory after garbage collection :62163768
free memory after integer allocation :62163768
memory used by allocation :0
free memory after collecting discarded integers :63164648

for code

import java.util.logging.Level;
import java.util.logging.Logger;

public class RunTime {

    public RunTime() {
        Runtime r = Runtime.getRuntime();
        //MEMORY MANAGEMENT
        long mem1, mem2;
        Integer intmatrix[] = new Integer[1000];
        System.out.println("Total memory is :" + r.totalMemory());
        mem1 = r.freeMemory();
        System.out.println("Initial free memory is :" + mem1);
        r.gc();
        try {
            System.out.println("Thread.sleep(2500)");
            Thread.sleep(2500);
        } catch (InterruptedException ex) {
            Logger.getLogger(RunTime.class.getName()).log(Level.SEVERE, null, ex);
        }        
        mem1 = r.freeMemory();
        System.out.println("free memory after garbage collection :" + mem1);
        for (int i = 0; i < 1000; i++) {
            intmatrix[i] = new Integer(i);
        }
        mem2 = r.freeMemory();
        System.out.println("free memory after integer allocation :" + mem2);
        System.out.println("memory used by allocation :" + (mem1 - mem2));
        for (int i = 0; i < 1000; i++) {
            intmatrix[i] = null;
        }
        r.gc();
        mem2 = r.freeMemory();
        System.out.println("free memory after collecting discarded integers :" + mem2);
    }

    public static void main(String[] args) {
        new RunTime();
    }
}
  • you can create a loop (100 times the same code with GC, with short delay 400-500 miliseconds instead of 2,5 sec) then you can to see (only sometimes but little bit different output from print out)

Edited 2 Years Ago by mKorbel

I tried this in NetBeans, latest Java 7. Just printed the allocation/1000. Ran it 100 times in a loop... I Got

memory used by allocation (k):1958
memory used by allocation (k):16
memory used by allocation (k):16
memory used by allocation (k):663
memory used by allocation (k):663
memory used by allocation (k):663
... the 663 same for the rest of the 100 iterations

I'm just going to add Java Garbage Collection to the long list of things I don't (need to?) understand!

@JamesCherrill +++ fully agree, I don't, you don't, never need to thinking about, cleanup, cleanup, cleanup rather than optimize Memory in GC

edit

very good point about OPs test logics

Edited 2 Years Ago by mKorbel

This question has already been answered. Start a new discussion instead.