在c#垃圾回收机制中,那些unreachable的对象会被回收,那什么样的对象是unreachable?
展开全部
主要处理步骤:将线程挂起→确定roots→创建reachable
objects
graph→对象回收→heap压缩→指针修复。可以这样理解roots:heap中对象的引用关系错综复杂(交叉引用、循环引用),形成复杂的
graph,roots是CLR在heap之外可以找到的各种入口点。
GC搜索roots的地方包括全局对象、静态变量、局部对象、函数调用参数、
当前CPU寄存器中的对象指针(还有finalization
queue)等。主要可以归为2种类型:已经初始化了的静态变量、线程仍在使用的对象(stack+CPU register) 。 Reachable
objects:指根据对象引用关系,从roots出发可以到达的对象。例如当前执行函数的局部变量对象A是一个root
object,他的成员变量引用了对象B,则B是一个reachable object。从roots出发可以创建reachable objects
graph,剩余对象即为unreachable,可以被回收 。
指针修复是因为compact过程移动了heap对象,对象地址发生变化,需要修复所有
引用指针,包括stack、CPU
register中的指针以及heap中其他对象的引用指针。Debug和release执行模式之间稍有区别,release模式下后续代码没有引用的
对象是unreachable的,而debug模式下需要等到当前函数执行完毕,这些对象才会成为unreachable,目的是为了调试时跟踪局部对象
的内容。传给了COM+的托管对象也会成为root,并且具有一个引用计数器以兼容COM+的内存管理机制,引用计数器为0时,这些对象才可能成为被回收
对象。Pinned
objects指分配之后不能移动位置的对象,例如传递给非托管代码的对象(或者使用了fixed关键字),GC在指针修复时无法修改非托管代码中的引用
指针,因此将这些对象移动将发生异常。pinned
objects会导致heap出现碎片,但大部分情况来说传给非托管代码的对象应当在GC时能够被回收掉。
每个对象都会被销毁,它的析构器会被调用
每个对象只销毁一次
每个对象只有在它不可抵达时(unreachable)时,换言之,不再存在到该对象的任何引用——才会摧毁。
楼主
objects
graph→对象回收→heap压缩→指针修复。可以这样理解roots:heap中对象的引用关系错综复杂(交叉引用、循环引用),形成复杂的
graph,roots是CLR在heap之外可以找到的各种入口点。
GC搜索roots的地方包括全局对象、静态变量、局部对象、函数调用参数、
当前CPU寄存器中的对象指针(还有finalization
queue)等。主要可以归为2种类型:已经初始化了的静态变量、线程仍在使用的对象(stack+CPU register) 。 Reachable
objects:指根据对象引用关系,从roots出发可以到达的对象。例如当前执行函数的局部变量对象A是一个root
object,他的成员变量引用了对象B,则B是一个reachable object。从roots出发可以创建reachable objects
graph,剩余对象即为unreachable,可以被回收 。
指针修复是因为compact过程移动了heap对象,对象地址发生变化,需要修复所有
引用指针,包括stack、CPU
register中的指针以及heap中其他对象的引用指针。Debug和release执行模式之间稍有区别,release模式下后续代码没有引用的
对象是unreachable的,而debug模式下需要等到当前函数执行完毕,这些对象才会成为unreachable,目的是为了调试时跟踪局部对象
的内容。传给了COM+的托管对象也会成为root,并且具有一个引用计数器以兼容COM+的内存管理机制,引用计数器为0时,这些对象才可能成为被回收
对象。Pinned
objects指分配之后不能移动位置的对象,例如传递给非托管代码的对象(或者使用了fixed关键字),GC在指针修复时无法修改非托管代码中的引用
指针,因此将这些对象移动将发生异常。pinned
objects会导致heap出现碎片,但大部分情况来说传给非托管代码的对象应当在GC时能够被回收掉。
每个对象都会被销毁,它的析构器会被调用
每个对象只销毁一次
每个对象只有在它不可抵达时(unreachable)时,换言之,不再存在到该对象的任何引用——才会摧毁。
楼主
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询