Where Are Static Methods and Static Variables Stored in Java

Where are static methods and static variables stored in Java?

Static methods (in fact all methods) as well as static variables are stored in the PermGen section of the heap, since they are part of the reflection data (class related data, not instance related). As of Java 8 PermGen has been replaced by MetaSpace and as per JEP 122 it only holds meta-data while static fields are stored in the heap.

Note that this mostly applies to Oracle's Hotspot JVM and others that are based on it. However, not every JVM has PermGen or Metaspace like Eclipse OpenJ9.

Update for clarification:

Note that only the variables and their technical values (primitives or references) are stored in PermGen space.

If your static variable is a reference to an object that object itself is stored in the normal sections of the heap (young/old generation or survivor space). Those objects (unless they are internal objects like classes etc.) are not stored in PermGen space.

Example:

static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.
A word on garbage collection:

Do not rely on finalize() as it's not guaranteed to run. It is totally up to the JVM to decide when to run the garbage collector and what to collect, even if an object is eligible for garbage collection.

Of course you can set a static variable to null and thus remove the reference to the object on the heap but that doesn't mean the garbage collector will collect it (even if there are no more references).

Additionally finalize() is run only once, so you have to make sure it doesn't throw exceptions or otherwise prevent the object to be collected. If you halt finalization through some exception, finalize() won't be invoked on the same object a second time.

A final note: how code, runtime data etc. are stored depends on the JVM which is used, i.e. HotSpot might do it differently than JRockit and this might even differ between versions of the same JVM. The above is based on HotSpot for Java 5 and 6 (those are basically the same) since at the time of answering I'd say that most people used those JVMs. Due to major changes in the memory model as of Java 8, the statements above might not be true for Java 8 HotSpot - and I didn't check the changes of Java 7 HotSpot, so I guess the above is still true for that version, but I'm not sure here.

Where are static variables stored in java 8?

Static methods and variables have been Stored in the PERMGEN space before the 8th version of the java. But,now they have introduced a new memory space called METASPACE now this is the place where all those name and fields of the class, methods of a class with the bytecode of the methods, constant pool, JIT optimizations etc are stored.
Reason for removing PERMGEN in java 8.0 is
It is very hard to predict the required size of PERMGEN..
It helps in improving Garbage Collection Performance and Class data-de allocation..

Ref: https://www.quora.com/Where-static-method-and-variables-stored-in-JVM

Where static is stored in java8 above version?

All code is held in metaspace.

All class metadata is held in metaspace.

All static variables are held in the heap.

So:

In conclusion, where static method, static variables, static class is stored in java8?

The answers are 1) metaspace, and 2) heap. For 3) it depends on what you mean. However the metadata is the only aspect of a static class that has a representation, and that is stored in metaspace.


Note that an application cannot get its hands on the actual method code, class metadata or frame containing the static variables.

Also note that class metadata, method code, and static frames not copied when (for example) objects are created.

So it is moot where they are actually stored.



Some article says static variables, static class can't be deleted by Garbage Collector.

Those articles are incorrect ... if that is what they actually say. The reality is that a class may be garbage collected if it becomes unreachable, but it is not easy to create the conditions in which a class becomes unreachable. So, in practice classes are rarely garbage collected.

Likewise, a classes static variables will become unreachable if the class itself is unreachable. But that is rare too; see above.

But anyway, the logical inference you were trying to make is incorrect. Being in the heap is neither necessary or sufficient for something to be reclaimed by one of the JVM's storage management mechanisms.

  • Things allocated in metaspace can be deleted.
  • Things allocated in the heap won't necessarily ever be eligible for deletion.

What is the actual memory place for static variables?

Static fields are initialised when a class is loaded and are discarded when the classloader for that class is unloaded. They can be cleaned up, even duplicated in another class loader.

For applications like those that use OSGi, static variables don't live for the whole life of the application. They can be reloaded many times.

How this is implement may be JVM dependent, but the Sun/Oracle JVM creates an "object" to hold the static fields for a class. This object is accessible via the Unsafe class which can also be used to examine this "objects" fields.

In Java, where is primitive static variables and static functions stored?

These are implementation details and we can't know for sure what each implementation does, without first reading and understanding its source code. As far as my knowledge and experience goes, the most reasonable things to assume (for a desktop JVM) are along these lines:

  • s and i are static variables. Static variables are probably allocated on the heap, in the permanent generation.
  • j is stored inside instances of class A. Class instances may live on the stack (if escape analysis for references can prove that the reference has automatic storage semantics - and they are small enough) or the heap (if escape analysis is not performed or is inconclusive or the instance is too large for the stack).
  • k is a local variable with automatic storage semantics, thus it should live on the stack. It's allocated when its containing method (getStaticString) is entered and it's deallocated when its containing method is exited.
  • l has the same semantics as k. The fact that its containing method (getString) isn't static, is irrelevant.
  • getString (and any other piece of user code, regardless of its linguistic attributes as static, non-static, etc) has two representations:
    • Its metadata and bytecode (AOT-compiled) are part of the class data of its containing class. Its lifetime in memory is likely to be linked with the loading/unloading of the class associated with this code, but not with any particular instance of that class. In other words, non-static methods aren't "created" every time you create an instance.
    • Its compiled code (JIT-compiled) should live permanently in a separate memory segment (a part of the JIT compiler's unmanaged heap, written to and then marked as executable), independent of the lifetime of the Java objects.

Understanding the difference between a static and a non-static method representation on the heap

There's another side of the story that needs to be mentioned. When you have a class, say Bar:

public class Bar {
public static void doSomething() { ... }

public void doSomethingElse() { ... }
}

On the heap the signature for doSomethingElse is not doSomethingElse() but doSomethingElse(Bar this). As opposed to doSomething which is left with no parameters (hence you can't call this from a static method - there is no this to call to).

When you have a call like this:

Bar bar = new Bar();
bar.doSomethingElse();

It's just a syntactic sugar to:

doSomethingElse(bar); // I neglected here for simplification but the name of the method in the compiled code also includes the name of the class.

When you define an extending class Foo:

public class Foo extends Bar {
@Override
public void doSomethingElse() { ... }
}

Another method is created doSomethingElse(Foo this). Next thing to there is a virtual table (read about it if you're not familiar with the term) - Each class holds a virtual table which maps a method signature to a concrete code. When you call a method in runtime there is a search in the class (not the instance) virtual table for the correct implementation according to the dynamic type of the instance.

So the full example would be (and of course that's just a simplification):

Java syntax (syntactic sugar):

Bar b = new Foo();
b.doSomethingElse();

What really happens (simplified):

// Step 1: Get the correct overriden method for Foo class from the virtual table
// Step 2: Invoke the method with the instance "b" as the first parameter (the "this" parameter)
Foo.getMethodFromVirtualTable("doSomethingElse").invoke(b);

That's only a simplification of course but that's sort of the way it happens.

In fact when you come to think of it, all the methods are static in memory (that's why they reside in PermGen). The complier uses the static virtual table for each class in order to call the correct method. This what allows polymorphism.



Related Topics



Leave a reply



Submit