问题
Yesterday, we had a discussion on Gargbage collection.
It was discussed that the objects created using Classes are collected by Garbage collector, but it cannot be collected by GC if it is being created using struct
I know that structures uses stack and classes uses heap.
But, I guess GC never collects unmanaged codes only. So does that mean that the Structure types are unmanaged code. (I don't think so).
OR is it that the GC take care of Heap only and not Stack?
If yes, then what about int data type. int is struct not class. So if we defined the object of type int, isn't it managed by GC?
回答1:
The GC will collect any managed objects (and Structures are managed objects) if they cannot be accessed from a GC root.
but it cannot be collected by GC, if it is being created using struct.
What you were told is incorrect. It doesn't matter how a managed object was created - if there are no references to it anymore, it will end up being collected.
OR is that means the GC take care of Heap only not Stack?
The GC takes care of the object graph - if objects are reachable by any of the GC roots, they will not be collected, if they are not, they will end up being collected. The Stack and Heap are not relevant.
So if we defined the object of type int, isn't it managed by GC?
int
(AKA System.Int32
) is a managed object - a structure. If you declare an int
field in a class and the class goed out of scope, the int
will end up being collected by the GC, for example.
As @leppie commented, in many situations, structures will get placed on the stack and when the stack is popped they will no longer exist - the GC, in such cases, is not involved (and doesn't need to be).
回答2:
it cannot be collected by GC if it is being created using struct.
Not true. If it's not referenced it will be collected eventually.
I know that structures use stack and classes use heap.
That is a common misconception. See this Lippert's article for details.
I think that the idea you're referencing to is that most often GC does not bother with collecting any data located on stack, because stack will be destroyed as soon as program execution leaves its scope. So that means that any data put directly into stack (which might mean value types and should mean references to all the other data) will be cleared automatically, no need to use GC. GC's work is to clear heap data independently of its (data) type. If it's not referenced - it's collected.
回答3:
But, I guess GC never collects unmanaged codes only. So is that means the Structure types are unmanaged code. (I don't think so).
I don't understand what you are asking here.
OR is that means the GC take care of Heap only not Stack?
Yes and No. GC takes care of memory required for instances of reference types (always created on the managed heap). You can view the "stack" as a piece of memory associated with current thread of execution. The stack can contain handles to reference types allocated on the managed heap. In this case the GC "cares": it will not collect the memory from the managed heap for these instances until these references on the stack exist. The stack can also contain instances (not references to!) of value types, in which case the GC does not care...
If yes, then what about int data type. int is struct not class. So if we defined the object of type int, isn't it managed by GC?
This question is a bit misleading. Let's say you "allocate" an instance of an int
on the stack:
void Foo()
{
// ...
int tTmp;
//...
}
In this case the GC does not care about tTmp
. It is placed on the current thread's stack and removed, if it gets out of scope. But if you do this:
void Foo()
{
//...
var tTmp = new int [] {
1, 2, 3, 4
};
//...
}
then the array of 4 integers is created on the managed heap and GC takes care of tTmp
. It also "indirectly" takes care of the memory required for the contents of the array, which happen to be the space required for the four integers...
回答4:
Let's see what the .NET standard (ECMA-334) says
Value types differ from reference types in that variables of the value types directly contain their data, whereas variables of the reference types store references to their data, the latter being known as objects. With reference types, it is possible for two variables to reference the same object, and thus possible for operations on one variable to affect the object referenced by the other variable. With value types, the variables each have their own copy of the data, and it is not possible for operations on one to affect the other.
In other words, there is no reason for garbage collector to care about value types, because they clean-up after themselves (when they go out of scope), they contain their own data. GC is for clean-up of shared (references) data.
Note that not only structures are value types:
A value type is either a struct type or an enumeration type. C# provides a set of predefined struct types called the simple types. The simple types are identified through reserved words.
So e.g. "int" type is so called "simple type", value type. It is bit different from other structures, because operations like +-*/ could end up being compiled into primitive operations, not function calls.
来源:https://stackoverflow.com/questions/11699740/is-it-true-that-garbage-collector-wont-collection-the-object-of-struct-type