Pawan
Pawan

Reputation: 32321

Java : Why there is no difference in JVM Heap Size even after Object Creation

I am trying to find out how JVM Heap Size would differ with Object creation .

For example if you see my below program , i am creating 10000 String Objects with in a for loop , but still there is no difference in Heap Size on to my JVM Environment .

public class One {

    public static void main(String args[]) {

        long heapSizebefore = Runtime.getRuntime().totalMemory();
        System.out.println("heapSizebefore" + heapSizebefore);

        for (int i = 0; i <= 10000; i++) {
            String str = new String();

        }

        long heapSizeafter = Runtime.getRuntime().totalMemory();
        System.out.println("heapSizeafter" + heapSizeafter);

    }

}

Upvotes: 1

Views: 175

Answers (4)

Peter Lawrey
Peter Lawrey

Reputation: 533432

Basically i wanted to know why we use Static Methods in Java.

Because static methods are simpler than instance methods.

so my question is to save memory (from object creation ) we use static Methods ??

No. You should code with purpose and only create things you actually need. You create an instance when you need to, and don't create one when you don't. This is not for performance reasons but to reduce the conceptual weight of your code. If you have to maintain your code, or some elses code, you need to find why is something being done and it takes alot longer to determine that pointless code really is pointless. i.e. It takes longer to look for something which is not there, than something which is.


To support multi-threaded memory allocation, each thread has a thread local allocation buffer or TLAB.

The free space only shows you how much is free in the common pool, but doesn't could the size available in each thread's TLAB. If you allocate enough strings, you will see a sudden jump in memory usage as it loads another block.

What you can do is turn this off with -XX:-UseTLAB

// -XX:+UseTLAB heapUsedBefore: 5,368,848 heapUsedAfter: 5,368,848
// -XX:-UseTLAB heapUsedBefore: 535,048 heapUsedAfter: 535,096

public class One {
    public static void main(String... args) {
        Runtime runtime = Runtime.getRuntime();
        long heapUsedBefore = runtime.totalMemory() - runtime.freeMemory();

        String str = new String();

        long heapUsedAfter = runtime.totalMemory() - runtime.freeMemory();
        System.out.printf("heapUsedBefore: %,d heapUsedAfter: %,d%n", 
                           heapUsedBefore, heapUsedAfter);
    }
}

Upvotes: 0

NPE
NPE

Reputation: 500157

Two reasons:

  1. You are measuring the amount of memory reserved for the heap, not the sum of the sizes of live objects.
  2. You don't keep references to the allocated strings anyway, so the JVM is free to garbage collect them whenever it wants.

Upvotes: 2

Matt Ball
Matt Ball

Reputation: 359776

The JIT is also likely optimizing away that entire for loop since it has no side-effects.

Upvotes: 2

Andrzej Doyle
Andrzej Doyle

Reputation: 103777

The call to totalMemory just gives you the amount of memory that's reserved by the Java process. It doesn't mean that it's actively being filled by objects on the heap. As the javadocs say, it is the total amount of memory available for current and future objects.

In fact Java will prefer to request memory in large chunks from the underlying operating system, rather than having to call malloc (or equivalent) every time a new object is created.

If you want to keep track of the actual size of the heap, you can do this simply in realtime by using a tool such as JConsole/JVisualVM, or in much more detail by using a memory profiler. If you want to do it programmatically, you'll need to register an agent for the complex stuff, but heap details are exposed through JMX. Have a look at the java.lang:Memory MBean's HeapMemoryUsage attribute (which is what JConsole uses to display the memory chart).

Upvotes: 4

Related Questions