views:

130

answers:

1

Hi,

This might be pretty basic, but was very curious to know. Here's the code snippet and the output

public class PlainSystemGC {

    public static void main(String ...strings) {

        System.out.println("Free Memory (Before GC): " + Runtime.getRuntime().freeMemory());

        System.gc();

        System.out.println("Free Memory (After GC): " + Runtime.getRuntime().freeMemory());
    }
}

and the output

Free Memory (Before GC): 1859640
Free Memory (After GC): 1911768

I am interested to know what is GC collecting here since no objects are created.

What's the memory thats being freed up ? ( and that too 52kb )


@JSauer - It gives Exactly the same results even if run 100 times

+8  A: 

On most JVM implementations the main method is not actually the first piece of Java code that is run during the JVM startup.

Usually, many parts of a complete JRE are themselves implemented in Java. For example a big part of the classloader mechanism is implemented in pure Java. It might even be able to write parts of the garbage collection algorithm itself in Java.

Due to this, there may already be some garbage from those system classes that the gc can collect even if your application created no garbage at all.

By the way, your application creates at least one object that is eligible for garbage collection at the point where System.gc() is called: The String that mentions the free memory is constructed dynamically and not held in a variable, so it could well be gc-ed during the System.gc() call.

Joachim Sauer
Very true. But, The string would not definitely consume 52K of memory ;) i believe ...
JWhiz
In addition, using a static field can cause class-initialization code to be run. For example, if the System class were not already initialized before main(), using System.out would cause it to be. See the language specification at http://java.sun.com/docs/books/jls/third_edition/html/execution.html#44557.
Andy Thomas-Cramer
I doubt that the `String` used in the `System.out` will be garbage collected. Even if it is not held in a variable, it is interned by `String` class since it is a literal.
Samit G.
@Joachim Sauer - I think samG is correct. Since its a literal, it may not be available for GC.
JWhiz
@samG: `"Free Memory (Before GC): "` is a string literal and won't be collected, that much is true. But the `String` that is built from concatenating the amount of free memory is **not** a string literal `"Free Memory (Before GC): 1859640"` and **is** eligible for GC.
Joachim Sauer
@Joachim - Adding two literals would be another literal in constant pool right ! Eg : this would print true`String s1 = "First" + "Second";String s2 = "FirstSecond";System.out.println(s1 == s2);``true`
JWhiz
@JWhiz: I'm **well** aware of this. But the return value of `Runtime.getRuntime().freeMemory()` is **not a literal** at all.
Joachim Sauer
@Joachim - How did I miss that concatenation (long day?). In fact, there isn't just a `String` being created there, there's also a `StringBuilder` object, which will be eligible for GC.
Samit G.
@samG or @ Joachim can you pls explain this more.. i know its long that is returned by freeMemory() .. Where does `StringBuilder` come into picture here .. and @ Joachim - My bad for pointing that out .. **ouch** ... i knw that's too trivial for you
JWhiz
@JWhiz: no problem with pointing that out, it's fine. `StringBuilder` comes into the picture since every String concatenation (that doesn't result in a compile time constant) will be converted to calls to `StringBuilder` by the compiler (earlier Java versions used `StringBuffer`, but other than that it worked the same): [JLS § 15.18.1.2 Optimization of String Concatenation](http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.18.1.2)
Joachim Sauer
@Joachim Thanks...
JWhiz