66

Say you have a class,

class Foo
{
    public static bar;
}

When you say:

new Foo();

I can imagine that in memory, a space is reserved for this object.

...and when you say again:

new Foo(); 

...well now you have another space available for the object.

However, where exactly does the static field live?

What I am really trying to learn is:

How do the references to the objects reference the same field of the objects they reference?

Rui Jarimba
  • 11,166
  • 11
  • 56
  • 86
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
  • 4
    This is already answered here: http://stackoverflow.com/questions/2142192/java-where-do-static-fields-live-within-the-memory – Santosh Kumar Pandey Feb 08 '13 at 22:04
  • @JesusPlusPlus Possibly, possibly not. Some languages have an entirely separate memory construct for static content besides the heap/stack. This is because they know that static content will always live forever, so there's no need for the GC (if there is one) to keep checking if it "is alive". It's always alive. – Servy Feb 08 '13 at 22:07
  • In Java, `bar` is stored with the definition of the `Foo` class. – Louis Wasserman Feb 08 '13 at 22:09
  • C doesn't have classes. I don't think you can mix static and non-static struct members in C. You should remove the C from this question. – Josh Petitt Feb 08 '13 at 23:27
  • @LouisWasserman the instance of bar, if one is created, will be on the heap (what the question is about is admittedly unclear). – assylias Feb 26 '13 at 20:21
  • 2
    Sorry, but the answer for your question it is really "it depends". Not only you are asking it for a wide array of different languages (C#, Java, ...) but it is an implementation detail in most of them. The only correct answer could be "somewhere where all the instances can access it" – Lorenzo Dematté Feb 28 '13 at 13:48

11 Answers11

120

While the exact details of the type system are implementation dependent, let me go into some more detail than just stating that it depends and you should not care. I'll describe how it approximately works in Microsoft's implementation (.NET) according to the book CLR via C# by Jeffrey Richter and the article See How the CLR Creates Runtime Objects by Hanu Kommalapati et al. (original MSDN May 2005 issue).


Say you have a class:

class Foo
{
    // Instance fields
    string myBar = "Foobar";
    int myNum;

    // Static fields
    static string bar = "Foobar";
    static int num;
}

Foo myFoo = new Foo();
Type typeOfFoo = typeof(Foo);

Where do the instance fields live?

Whenever you say new Foo(), space is allocated and initialized for the object instance, and the constructor is called. This instance is shown as instance of Foo in the image below. Such as instance contains only the instance fields of the class (in this case myBar and myNum), and for objects allocated on the heap two extra fields used by the runtime (Sync block index and Type handle). The type handle is a pointer to a Type object that describes the type of the instance, in this case type of Foo.

When you say new Foo() again, new space is allocated which will again contain space for the instance fields of the type. As you can see, instance fields are associated with object instances.

The runtime puts each instance field at a fixed offset from the start of the object's data. For example, myBar might live at offset +4. The address of the instance field is simply the address of the object plus the offset of the field.

Where do the static fields live?

Static fields in C# and Java are not associated with any object instance, but with a type. Classes, structs and enums are examples of types. Only once (per type) is some space allocated to hold the values of the static fields. It would make sense to allocate space for the static fields in the Type structure that describes the type, since there is also only one Type object per type. This is the approach taken by C# and Java.

The Type object1 is created when the type is loaded by the runtime. This structure contains all sorts of information needed for the runtime to be able to allocate new instances, call methods and perform casting, among other things. It also contains the space for the static fields, in this case bar and num.

The runtime has put each static field at some offset from the start of the type's data. This is different for each type. For example, bar might live at offset +64. The address of the static field is the address of the Type object plus the offset of the field. The type is statically known.

Displays some object structures, and their relationships.

1) In Microsoft .NET multiple different structures describe a type, such as the MethodTable and the EEClass structures.

Daniel A.A. Pelsmaeker
  • 47,471
  • 20
  • 111
  • 157
  • 3
    Can you explain why the arrow from string myBar of instance of Foo and the static string bar from type of Foo somehow meet and point to instance of String? – Koray Tugay Mar 06 '13 at 18:39
  • 7
    @KorayTugay In the code above both fields are set to the string `"Foobar"`. Due to [_string interning_](https://en.wikipedia.org/wiki/String_interning) they'll point to the same String instance. – Daniel A.A. Pelsmaeker Mar 07 '13 at 10:29
  • +1 Great post! Can you please explain what is `Sync block index` for? I am unable to find any relevant content. – Agent007 Apr 21 '14 at 05:53
  • 2
    @Agent007 The sync block index is the index of the synchronization block of an object in the sync block table. Not all object have a sync block. The sync block contains (among other things) the hash code for the object and whether a lock has been acquired on the object. – Daniel A.A. Pelsmaeker Apr 21 '14 at 08:51
  • What an answer. Simply fabulous! Btw, what does those two `//` represent in the arrow connecting `type of Foo` box and `instance of String` boxes? I thought it might be related to UML diagrams but I couldn't find any. – RBT Jan 25 '18 at 00:12
  • @RBT My diagram is not a proper UML diagram. The `//` means I left out some details/arrows. – Daniel A.A. Pelsmaeker Jan 26 '18 at 08:40
  • Nice explanation! So, just to ensure that I don't misunderstand: This means that no matter how many times the class is instantiated, the static fields / properties will not consume additional memory (beyond those consumed by the type), right? – pepoluan Jun 04 '21 at 10:40
  • @DanielA.A.Pelsmaeker, so does this mean that the myFoo points both to a class object and THE type object? – Eric Movsessian Jun 18 '22 at 15:10
16

This completely depends on the implementation in question. For C# and Java, the runtime is allowed to determine where to store the memory for the variable. For C and most compiled languages, the compiler makes this determination.

That being said, in practice, it doesn't matter. The usage it determined by specification, so you are free to use the variable knowing the behavior will be guaranteed.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • I don't know aout c#, but Java VM specifications require that objects be stored on the heap. References (pointers) to those objects might be on the stack. – assylias Feb 26 '13 at 22:50
6

For Java, objects referred to by static fields will reside on the heap like other objects:

The heap is the runtime data area from which memory for all class instances and arrays is allocated.

The field will be initialised (if the declaration contains an initialization) when the class is loaded, which happens immediately before the first occurrence of any one of the following:

  • an instance of the class is created.
  • a static method declared by the class is invoked.
  • a static field declared by the class is assigned.
  • a static field declared by the class is used and the field is not a constant variable (§4.12.4).

The access to the static field is done via 2 special JVM instructions, getstatic and putstatic. But apart from that distinction, static fields are similar to non static fields.

assylias
  • 321,522
  • 82
  • 660
  • 783
5

This varies wildly from language to language, and can even vary wildly from platform to platform...

For example, on the .NET side, static members are "associated" with the governing EEClass definition, which can be a heap-allocated OR a "wherever" allocated member (the C# spec doesn't specify heap/stack behavior, it's an implementation detail of the VM)

JerKimball
  • 16,584
  • 3
  • 43
  • 55
5

Im only familiar with C#, and this is my understanding of it:

Then your program starts, it loads all the related assemblies into an AppDomain. When the assambly is loaded, all static constructors are called, including static fields. They will live in the there, and the only way to unload them, is to unload the AppDomain.

Jens Kloster
  • 11,099
  • 5
  • 40
  • 54
  • 3
    static constructors are called on demand, when the types are actually used... – Servy Feb 08 '13 at 22:06
  • @Servy I'm being slightly pedantic, but isn't it when the Type is *referenced*, not necc. *used*? (not that there's much difference) – JerKimball Feb 08 '13 at 22:11
  • @JerKimball I consider referencing it to be using it, so my statement is slightly more vague then it needs to be, but it's not technically *wrong*. A more formal statement would be to say that the static constructor is called at some point before any member (static or non-static) of that type is referenced either in code or through reflection. – Servy Feb 08 '13 at 22:13
  • @Servy Like I said, I was being pedantic :) Did you see (I think it was Lippert)'s post on this recently? – JerKimball Feb 08 '13 at 22:15
  • @JerKimball: Next week's posts will give some interesting example of situations where it looks like a type is being used, but really it isn't. – Eric Lippert Feb 08 '13 at 23:14
5

There might be exceptions, but for reference types the new-keyword usually creates an object in an internal data structure called "heap". The heap is managed by the CLR (Common Language Runtime). It makes no difference whether you have a static or instance member or a local variable.

The difference between static members and instance members (the ones without the keyword static) is, that static members exist only once per type (class, struct) and instance members exist once per instance (per object).

It is only the reference which is static or not; this distinction does not apply to the referenced object (unless the object is a value type). A static member, an instance member and a local variable can all reference the same object.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
3

Static members and constants are stored on heap. Unlike objects on heap that can get garbage collection, Static members and constants do stay till Appdomain is torn down, Hence once should be carefull in dealing with static fields

2

Static variables belong to the class not the object so there is only one bar in the memory even if you initialize thousands of instants of Foo.

Can Geliş
  • 1,454
  • 2
  • 10
  • 19
  • 1
    Which doesn't answer the question. Where is the memory for the `Foo` class stored? – Servy Feb 08 '13 at 22:05
  • 1
    @Servy, no I think he is right, it is an acceptable answer: " Where is the memory for the Foo class stored" is not something you can answer for C#,Java,PHP,... It is just "somewhere, in a unique location for calss Foo" – Lorenzo Dematté Feb 28 '13 at 13:50
  • 1
    You could say they belong in the heap somewhere.. No matter what language you'll find them "somewhere" in the heap. The exact location is irrelevant, just remember that there's only 1 copy of each and that by being in the heap they have long lives (till script termination in php..). Imagine that this one space in heap has a pointer to it and each time you initialize an object the object gets a copy of that pointer to it's static property. – smassey Mar 04 '13 at 15:33
1

This depends on the language to language or the designer of the language. If I talk about Java, static members store in the Method area of the JVM and all the object are linked to them. One more thing that is very important to know is that we can access the static data member without creating the object of the class.It means the allocation of the memory to the static data members doesn't depend on the creation of the object of that class.

Jatin Khurana
  • 1,155
  • 8
  • 15
1

By specification static variables are stored in Constant Pool. JVM stores this info in Permanent Generation.

Mikhail
  • 4,175
  • 15
  • 31
0

Typically Static variables are stored on the data-segment of the program memory. so for every class that is created/is in the running program will create the static variable on data-segment and all other variables are initialized in the code segment.

so basically it is like

+++++++++++++++++++++++++++++++++++++
+ DATA Segment
+   -static vars
+   
+----------------------------------
+  instances | instances | instances|
+            |           |          |

here single area is shared among instances.

from wikipedia "The data area contains global and static variables used by the program that are
explicitly initialized with a value."

Jitendra
  • 1,107
  • 2
  • 12
  • 22