Question

This question is for the java language in particular. I understand that there is a static protion of memory set aside for all static code.

My question is how is this static memory filled? Is a static object put into static memory at import, or at first reference? Also, do the same garbage collection rules apply to static objects as they do for all other objects?


public class Example{
    public static SomeObject someO = new SomeObject();
}
/********************************/
// Is the static object put into static memory at this point?
import somepackage.Example;

public class MainApp{
    public static void main( Sting args[] ){
// Or is the static object put into memory at first reference?
       Example.someO.someMethod();
// Do the same garbage collection rules apply to a 
//     static object as they do all others?
       Example.someO = null;
       System.gc();
    }
}
Was it helpful?

Solution

Imports don't correlate with any instructions in compiled code. They establish aliases for use at compile time only.

There are some reflective methods that allow the class to be loaded but not yet initialized, but in most cases, you can assume that whenever a class is referenced, it has been initialized.

Static member initializers and static blocks are executed as if they were all one static initializer block in source code order.

An object referenced through a static member variable is strongly referenced until the class is unloaded. A normal ClassLoader never unloads a class, but those used by application servers do under the right conditions. However, it's a tricky area and has been the source of many hard-to-diagnose memory leaks—yet another reason not to use global variables.


As a (tangential) bonus, here's a tricky question to consider:

public class Foo {
  private static Foo instance = new Foo();
  private static final int DELTA = 6;
  private static int BASE = 7;
  private int x;
  private Foo() {
    x = BASE + DELTA;
  }
  public static void main(String... argv) {
    System.out.println(Foo.instance.x);
  }
}

What will this code print? Try it, and you'll see that it prints "6". There are a few things at work here, and one is the order of static initialization. The code is executed as if it were written like this:

public class Foo {
  private static Foo instance;
  private static final int DELTA = 6;
  private static int BASE;
  static {
    instance = null;
    BASE = 0;
    instance = new Foo(); /* BASE is 0 when instance.x is computed. */
    BASE = 7;
  }
  private int x;
  private Foo() {
    x = BASE + 6; /* "6" is inlined, because it's a constant. */
  }
}

OTHER TIPS

There is normally no such thing as "static" memory. Most vm's have the permanent generation of the heap (where classes get loaded), which is normally not garbage collected.

Static objects are allocated just like any other object. But, if they live for long they will be moved between the different generations in the garbage collector. But they will not end up in permgenspace.

If your class is holding onto this object permanently, it will only be released when the vm exits.

This static variable some0 is initialized as soon as your class is referenced in your code. In your example this will be executed in first line of your main method.

You can validate this by creating a static initializer block. Put a break point in this initializer block and you'll see, when it will be called. Or even more simplier... put a breakpoint in the constructor of SomeObject.

The initialization of static variables is covered in Section 2.11 Static Initializers of suns JVM spec. The specification does not define the implementation of Garbage collection however so I imagine that garbage collection rules for static objects will vary depending on your VM.

It should be noted, that only the pointer (or any other primitive type) is stored in the PermGenSpace (thats the proper name for the area where the static stuff is stored).

So the Object referenced by the pointer sits in the normal heap, like any other object.

If the static field is changed to reference a different object, the original object pointed to by the static field is eligible for GC just like any other object.

It could also be free'ed (even if not nulled) if the class itself is unloaded and the entire object graph is cut from the heap. Of course, when a class can be unloaded is a good topic for a host of other questions... :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top