Are static fields open for garbage collection?
Static variables cannot be elected for garbage collection while the class is loaded. They can be collected when the respective class loader (that was responsible for loading this class) is itself collected for garbage.
Check out the JLS Section 12.7 Unloading of Classes and Interfaces
A class or interface may be unloaded
if and only if its defining class
loader may be reclaimed by the garbage
collector [...] Classes and interfaces
loaded by the bootstrap loader may not
be unloaded.
Can an activity be garbage collected if it has static member variables who are referenced elsewhere?
Classes for example purposes
public class Activity {
public static int primitiveStatic = 42;
public static Object objectStatic = new Object();
}
public class B {
public Object referenceField = null;
}
public class C {
public int primitiveField = 0;
}
A simple model of a Java object instance is a memory area containing, in addition to space for each of its instance members (non-static), some administrative information including a reference to its class object. The class object (the entity in memory at runtime) contains various pieces of information about the class, including (relevant to this question) space for each of the static members of the class. Note that some of this is JVM dependent.
The key thing to note is that static members are stored in or with the class object at runtime (not in any instance object).
In the example classes above, the Activity
class object at runtime would have two variables, one primitive integer variable (primitiveStatic
) and one reference of Object
type (objectStatic
). Every instance of the class would have its own distinct memory area, containing not much more than a single reference to the class object. An instance of B
has space for a single object reference. An instance of C
has space for a single primitive integer value.
The garbage collector can remove and finalize any object in memory which is eligible for collection. This does apply also to class objects, but it is not as simple as for instance objects, where the object is eligible if there are simply no references to it. Class objects and static fields are rarely eligible, but in cases where the class is unloaded, they are. See this documentation for more information on class unloading.
I believe the cases you are wondering about include these:
Case 1
new Activity();
//or
Activity a = new Activity();
a = null;
Case 1 after set up and assignments are completed.
The class is loaded, creating the class object and static variables as described above. An instance is created, as described above. The instance is immediately eligible for garbage collection. When collected, the instance is destroyed, removing the reference to the class object. If it is the end of the program or in other certain cases, the class object may also be garbage collected, removing the primitiveStatic
and objectStatic
variables. In this case, the new Object()
which was referred to by objectStatic
now also has no references to it, and is in turn eligible for garbage collection in the normal way.
Case 2
B b = new B();
b.referenceField = Activity.objectStatic;
Case 2 after setup and assignments are completed.
A new B
instance is created (and the class object for class B
) as described above. The Activity
class is loaded and class object created if it has not been already. The referenceField
in b
is set to refer to the same location as the objectStatic
field, which is found in or with the Activity
class object. If the Activity
class is unloaded (happens in some cases but not common), its class object is removed as described in //1
. This time, the new Object()
still has a reference to it, in b.referenceField
, so is not eligible for collection. We are left with the B
class object and the new Object()
and an instance, b
, with a single reference to each.
Case 3
Activity a = new Activity();
B b = new B();
b.referenceField = a.objectStatic;
a = null;
Case 3 after setup and assignments are completed.
The Activity
class is loaded, and class object created if they aren't already, as described above. An instance is created, as described above. The same for the B
class. By finding a
's class reference and locating it there, the static reference objectStatic
is obtained from a
and assigned to b.referenceField
. This is a copy assignment of the reference value, so there is no reference between b
and a
or Activity
, but b
now contains a reference to the new Object()
constructed by the Activity
class. a = null
means that the Activity
instance initially referred to by a
becomes eligible for garbage collection. Its reference to the Activity
class object is removed. The Activity
class object may become eligible for garbage collection. If it is, the static fields it contains are cleared. The new Object()
referred to by objectStatic
now has a single reference, in b
, so is not eligible for garbage collection. We are left with this object, and the B
class object, and b
which contains a single reference to each (identical to case //2
)
Case 4
Activity a = new Activity();
C c = new C();
c.primitiveField = a.primitiveStatic;
a = null;
Case 4 after setup and assignments are completed.
Like in //3
, the Activity
class is loaded, and class object created if they aren't already, and an instance is created, as described above. The same for the C
class. By finding a
's class reference and locating it there, the static primitive primitiveStatic
is obtained from a
and assigned to c.primitiveField
. This is simply a copy assignment, so there is no reference between c
and a
or Activity
. a = null
means that the Activity
instance initially referred to by a
becomes eligible for garbage collection. Its reference to the Activity
class object is removed. The Activity
class object may become eligible for garbage collection. If it is, the static fields it contains are cleared. The new Object()
referred to by objectStatic
now has no references, so is eligible for garbage collection. We are left with the C
instance, c
, with a primitive int value of 42 in its primitiveField
.
In all of these cases, no object instance is prevented from being garbage collected by something else having references to objects also referred to by its class static fields (and even the class and its static values can be garbage collected in certain circumstances), even when those field values are 'owned' by the class (e.g. final
and initialised in and by the class.)
Things to watch out for are that if the objectStatic
field is final
, the object it refers to will almost never be collected: the Activity
class must be unloaded for it to become eligible for collection. This could be a problem if you have lots of static object references which are not used after program setup, since they will stick around and fill up memory even though they aren't used.
Do static members ever get garbage collected?
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.)
Garbage collection of static members
Objects referenced by static variables will only be garbage collected when the relevant AppDomain
is garbage collected. In client applications, there's often just a single AppDomain
which lives for the duration of the process. (An exception is when the application uses a plug-in architecture - different plug-ins may be loaded in different AppDomain
s and the AppDomain
may be unloaded later.)
In ASP.NET, "AppDomain
recycling" happens periodically (for various reasons) - when this occurs, and the static variables within that AppDomain
will no longer act as GC roots, and thus won't prevent objects being garbage collected.
If you were worried about an object being garbage collected while you still had a reference to it via a static variable, though, you can relax. While you can access the object, it won't be garbage collected.
Are dereferenced static variables garbage collected?
Variables aren't garbage collected, and aren't dereferenced either. Objects are garbage-collected, maybe, if there are no references. static
really has nothing to do with it.
EDIT
Okay I think I get it.
Let's see.
There are no static objects per se, there are static references.
Correct.
Static references persist throughout the application life-cycle, and are never garbage collected.
Incorrect. Static references are held in class objects. Those class objects can be garbage-collected under some circumstances. It is meaningless to speak of references being garbage-collected.
Therefore, any object they point to will not be garbage collected.
There is no 'therefore' about it. An object is eligible for garbage-collection when there are no more references to it. Zero. One object containing a reference to it being garbage-collected is necessary but not sufficient. There have to be no other references, and the garbage-collector has to actually reach the object.
Additionally, all non-static references that go out of scope will be garbage collected.
Incorrect. It is meaningless to speak of references being garbage-collected.
Is my understanding correct?
No.
Does the garbage collector work on static variables or methods in java?
static fields are associated with the class, not an individual instance.
static fields are cleaned up when the ClassLoader which hold the class unloaded. In many simple programs, that is never.
If you want the fields to be associated with an instances and cleaned up then the instance is cleaned up, make them instance fields, not static ones.
Can garbage collector run on Static class objects
Short answer : No. Marking your class static may NOT save it from garbage collection
Making a class static may avoid garbage collection for the particular class loader which was responsible for loading it. However, if this classloader gets opted for garbage collection, then all classes loaded via it ( static or non-static ) will also be garbage collected.
Usually this is the case when you have multiple class loaders in your application.
Other than that, an object ( any object ) is opted for garbage collection when it becomes unreachable
From the JLS (source)
A class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector [...] Classes and interfaces loaded by the bootstrap loader may not be unloaded.
Related Topics
Uwp Binding in Style Setter Not Working
C# Version of Openssl Evp_Bytestokey Method
Implicit Typing; Why Just Local Variables
Concat All Strings Inside a List<String> Using Linq
How to Get This ASP.NET MVC Selectlist to Work
Convert Any Object to a Byte[]
What Is the Minimum Client Footprint Required to Connect C# to an Oracle Database
Multiple Actions Were Found That Match the Request in Web API
How to Transform String to Utf-8 in C#
Usercontrol' Constructor with Parameters in C#
Regular Expression to Split on Spaces Unless in Quotes
How to Pass Values Across the Pages in ASP.NET Without Using Session