47

Do static member variables ever get garbage collected?

For example, let's use the following class.

public class HasStatic {
    private static List<string> shared = new List<string>();

}

And supposed that it's used like this:

//Startup
{
HasStatic a = new HasStatic();
HasStatic b = new HasStatic();
HasStatic c = new HasStatic();
HasStatic d = new HasStatic();
//Something
}
//Other code
//Things deep GC somewhere in here
HasStatic e = new HasStatic();

When a, b, c, and d are garbage collected does the static member shared get collected as well? Could e possibly get a new instance of shared?

Jader Dias
  • 88,211
  • 155
  • 421
  • 625
C. Ross
  • 31,137
  • 42
  • 147
  • 238
  • Keep in mind that `a.shared[1]` will have the same value as `b.shared[1]`, and that this element of `HasStatic` can also be referenced via `HasStatic.shared[1]`. (Assuming, of course, that there are at least 2 elements in the `shared` list.) –  Jul 06 '11 at 16:56

2 Answers2

82

No, static members are associated with the Type, which is associated with the AppDomain it's loaded in.

Note that there doesn't have to be any instances of HasStatic for the class to be initialized and the shared variable to have a reference to a List<string>.

Unless you're considering situations where AppDomains get unloaded, static variables can be regarded as GC roots forever. (Of course, if something changes the value of HasStatic.shared to reference a different instance, the first instance may become eligible for garbage collection.)

Brian Webster
  • 30,033
  • 48
  • 152
  • 225
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 3
    +1. I was pretty certain about this, but would have needed to test to verify. ...maybe even look it up in my *C# in Depth* book! LOL –  Jul 06 '11 at 16:54
  • 3
    There are two exceptions that should be mentioned. Anything referenced via `WeakReference` can be garbage collected, as are any static members instantiated as `ThreadLocal` whose thread terminates. – LBushkin Jul 06 '11 at 19:53
  • This is a really old answer, I know, but I have a follow-up question, Jon: Given your last remark in parenthesis: What decides if the original instance is eligible for garbage collection or not? – Christian Rygg Oct 30 '15 at 09:19
  • @ChrisRidge: The same as anything else: whether there's any way of getting to the object, basically. – Jon Skeet Oct 30 '15 at 09:21
  • 1
    What if you set the static member to `null`? From what I've been reading, this will make it available for GC. – Mike Lowery Jun 02 '16 at 14:12
  • @DiskCrasher: Well, that would mean that the static variable would no longer *stop* an object variable from being garbage collected, yes. – Jon Skeet Jun 02 '16 at 14:14
30

The only thing I would add to Jon's excellent answer is that CLR 4 supports "collectible assemblies". If you dynamically generate a collectible assembly then the statics of its types go away when the assembly is garbage collected.

See this msdn article for a brief overview of the feature:

http://msdn.microsoft.com/en-us/library/dd554932%28VS.100%29.aspx

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • How well do those work in practice? Isn't there a lot of (user)code that caches reflection data and thus keeps the types and assemblies alive? – CodesInChaos Jul 06 '11 at 18:23
  • 1
    @CodeInChaos: If user code caches data that keeps a larger object alive then The System Works. That's the whole point of garbage collection, is to keep reachable stuff alive. The justification for collectible assemblies is the opposite problem: we would like to be able to generate temporary code in temporary assemblies that goes away when it is all unreachable. We could not do that before collectible assemblies. – Eric Lippert Jul 06 '11 at 18:31
  • I mean that code accidentally keeps that collectible assembly alive by caching type related information that's obsolete once the type were to no longer exist. I've created a question since this is a bit too complicated to discuss in comments: http://stackoverflow.com/questions/6601502/caching-reflection-data – CodesInChaos Jul 06 '11 at 18:56
  • 1
    @Eric: It may also be worth mentioning WeakReferences and ThreadLocal members as well, then. – LBushkin Jul 06 '11 at 19:55
  • @Eric Lippert: How can I check if handler (handler method class) is member of collectible assembly? – Yarl Sep 15 '17 at 07:30
  • @HugoUchoBruno: That sure sounds like a great question to post on StackOverflow. – Eric Lippert Sep 15 '17 at 08:46
  • @Eric Lippert: NP – https://stackoverflow.com/questions/46237938/how-can-i-check-if-handler-handler-method-class-is-member-of-collectible-assem. – Yarl Sep 15 '17 at 10:57