Is it possible to create an "Island of Isolation" scenario in .NET?
I have been reading about garbage collection and came to know the term "Island Of Isolation", such as when ObjectA references to ObjectB and ObjectB simultaneously references to ObjectA.
Can someone give me an example of this in C#? Also, can you please explain if this is the same thi开发者_如何学Pythonng as a "memory leak"?
The island of Isolation is typically a problem in GCs that use reference counters. ObjectA and ObjectB in the scenario you described so both have a reference count of 1 and so won't be collected even though nothing else can reach it.
This however doesn't happen in .NET because .NET's GC uses a mark and sweep algorithm. It starts at the roots and creates an object graph so only items that are rooted will survive a collection. This means nothing can be "Isolated"
The garbage collector in .Net doesn't use reference counting to know when it can collect an object. Instead, it builds an object graph where objects that are currently accessible (read: in scope or global) are at the root of the graph. It then uses the graph to see whether each object in memory is connected to the root; anything that is not connected to the root is said to be "unrooted" and can be collected. This is true even if other objects have references to an unrooted object, as long as those objects are also not rooted. This way, that "Island of Isolation" you're talking about just isn't a problem.
Example from: When is an object eligible for garbage collection?
class Person {
public Person firend;
public static void main(String[] args) {
Person obj1 = new Person();
Person obj2 = new Person();
obj2.firend = obj1;
obj1 = null; //Line A
obj2 = null; //Line B
.....
}
}
After Line A executes, The object obj2 still has a reference to the object obj1 and the object obj2 is still referenced by the variable obj2. Therefore, the object obj1 can not be eligable for garbage collection. After Line B exectues, there are no more references to the object obj2. There still is a reference to object obj1 inside the object obj2. Now, the object obj1 and obj2 has no reference from root set of references. Therefore, both of objects are eligible for garbage collection.
Well that certainly doesn't leak in .NET. For example:
public class Foo
{
public Foo Bar { get; set; }
}
...
static void Main()
{
Foo f1 = new Foo();
Foo f2 = new Foo();
f1.Bar = f2;
f2.Bar = f1;
// Not actually required so long as nothing in the rest of the method
// references f1 and f2
f1 = null;
f2 = null;
// The two Foo objects refer to each other, but they're both eligible for
// garbage collection.
}
In a ref-counted system this would leak memory - in the .NET GC, it doesn't. When the GC runs, it will find all objects reachable from known roots; anything unreachable can be garbage collected.
精彩评论