3

I have written simple code in java as follows

public static void main(String[] args) {
    String st ="Java";
    StringBuffer sb = new StringBuffer(st); 
    long startTime = System.currentTimeMillis();
    Runtime r = Runtime.getRuntime();
    long startm = r.freeMemory();

    System.out.println("Before running program free memory is: "+startm);

    for(int i=0; i<10000; i++)
        st+="is";

    long endm = r.freeMemory();
    System.out.println("After program free memory is: "+endm);
}   

However the problem is when I run the program, free memory is increasing after loop is finished but it should be less than in beginning of the program. My output is as follows:

Before running program free memory is: 61089768

After program free memory is: 123747064

Please tell me why is that?

Saif Asif
  • 5,516
  • 3
  • 31
  • 48
  • 1
    "Current allocated free memory, is the current allocated space ready for new objects. Caution this is not the total free available memory". Source: http://stackoverflow.com/questions/3571203/what-is-the-exact-meaning-of-runtime-getruntime-totalmemory-and-freememory. Java is allocating more space for new objects, based on your previous operation. – Sean Perkins Dec 14 '15 at 05:22
  • Memory may depend on a number of external factors as well of the system. If your purpose is to test memory usage, I suggest you properly `benchmark` your code. – Saif Asif Dec 14 '15 at 05:23

1 Answers1

2

Your code is producing a lot of object garbage. The line

st+="is";

translates to:

st = new StringBuffer().append(st).append("is").toString();

This means each loop produces at least two objects of garbage.

Before entering the loop, there is already garbage on the object heap from the Java startup. Your loop triggers the garbage collector, freeing not only the unneeded objects from your program, but also all other objects left behind by the Java startup.

Start your program with the parameters -XX:+PrintGCDetails and you will see when the GC operates.

cruftex
  • 5,545
  • 2
  • 20
  • 36
  • Not only that: the heap will also be expanded to accommodate for the memory needs. – Thomas Kläger Dec 14 '15 at 06:12
  • @ThomasKläger: That is theoretical possible, but very unlikely, since in the loop a maximum of 79996 bytes is needed for the strings, plus some object overhead. – cruftex Dec 14 '15 at 06:17
  • on the contrary I think it is very plausible if the free memory increases from about 60 Megabytes to about 120 Megabytes – Thomas Kläger Dec 14 '15 at 06:42
  • Thanks for your help. I have a question. I know it's producing a lot of garbage. So, i thought that it will reduce the free memory. But with garbage value free memory is increasing. Why is that? It should consume the memory & slow down the program. Actually I made this program to test the memory taken by concating & StringBuffer. – Brijesh Maurya Dec 14 '15 at 07:43
  • Since the heap size can increase any time (as long as it stays below the maximum heap size) you should look at the difference between total memory and free memory: `r.totalMemory() - r.freeMemory()` – Thomas Kläger Dec 14 '15 at 13:04
  • The heap would only increase after an GC run. Again, if you really want to see what is going on: -XX:+PrintGCDetails – cruftex Dec 14 '15 at 16:08
  • Furthermore: The usage of StringBuffer is has no effect here. The variable `sb` is used nowhere. Please look on some examples, read the JavaDocs and make sure you understand the basic semantics. – cruftex Dec 14 '15 at 16:10