Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET垃圾收集器能否收集作为类成员的对象?_C#_.net_Garbage Collection - Fatal编程技术网

C# .NET垃圾收集器能否收集作为类成员的对象?

C# .NET垃圾收集器能否收集作为类成员的对象?,c#,.net,garbage-collection,C#,.net,Garbage Collection,我有一个类,它包含一个指向从IDisposable继承的对象的指针 class Foo { private Bar bar; private test() { bar = CreateBarFactory(); } }; 在test()中,如果设置了bar,则永远不会使用bar 我想知道,即使Foo实例仍然存在,GC是否允许处理bar 如果是这样的话,我有什么办法可以防止这种情况发生吗?bar是指向包含ref计数的对象的指针,如果它被释放

我有一个类,它包含一个指向从IDisposable继承的对象的指针

class Foo 
{
    private Bar bar;

    private test() 
    {
        bar = CreateBarFactory();
    }

};
在test()中,如果设置了bar,则永远不会使用bar

我想知道,即使Foo实例仍然存在,GC是否允许处理bar


如果是这样的话,我有什么办法可以防止这种情况发生吗?bar是指向包含ref计数的对象的指针,如果它被释放(),则ref被释放,导致某些功能被禁用

如果foo实例仍然存在(即有人持有对它的引用..保持它的活动状态),bar将不会被收集。GC将其视为“可到达”,即在使用中


可访问对象的成员也被认为是可访问的。

请不要混淆术语。C#确实有指针,但你没有。你有推荐人。重要的是,引用确实会影响垃圾收集器,而指针本身不会。(*)

只要
Foo
的实例是可访问的,它对
bar
的引用也将保持该对象的可访问性。如果
Foo
Bar
有终结器,那么在
Foo
的终结器中,您不应该假设关于
Bar
的任何内容-它可能已经自己终结了

尽管如您所示,不会调用访问
bar
的其他方法,但GC和JIT不会执行此类分析。对于对象引用,整个对象被认为是可访问的,它包含的任何引用都将被跟踪,并且类似位置的对象将被标记为可访问。必须这样做,以便基于反射的对象访问永远不会获得无效引用。这也是为什么,如果您的对象已分配了一个不再使用的大型辅助对象,那么(在这种有限的情况下)将引用设置为
null

唯一考虑到未来代码运行的生存期分析是关于局部变量的单个方法体中的代码。如果不再引用某个方法中的局部引用变量,则该方法中的局部引用变量不足以使该对象保持活动状态。这是JIT和GC之间协作完成的


(*)人们有时认为指针使对象保持活动状态。严格来说,这不是事实。钉住的动作可以产生一个指针,它可以使一个对象保持活动状态,但是没有什么可以阻止你在对象被钉住的时间之外保持一个指针。当然,在任何时候取消引用指针都是不安全的


还有另一个术语问题:

我想知道GC是否被允许处理酒吧

GC不会处理任何东西。当对象实现IDisposable并且对象的用户在其上调用
Dispose
(直接调用或通过
使用
块调用)时,发生处置


GC不调用
Dispose
。如果在对象上定义了终结器(我上面的警告也适用),它可能会调用终结器,然后收集对象。

要正确使用此类,您应该从
IDisposable
iterface继承它,并实现方法
Dispose()
,该方法将调用
bar.Dispose()
。它将保证这个扩展资源将在可以释放的时候被释放,而不是在GC决定收集时被释放。

为了防止它(如果它会发生),您应该先查看这个我想了解它。您已经创建了一个bar对象,并将其分配给foo类中的一个bar实例。现在,如果您有一个Foo的实例,并且bar已被释放。根据这一理论,食物不会被GC收集,而酒吧将保持原样,不会被处置。我明白,我的问题实际上归结为什么是可以到达的。是一个类的成员,除了被设置外从未使用过,被认为是可访问的“如果foo实例仍然存在,则不会收集bar。”-不一定!如果Foo是不可访问的,那么即使Foo的实例方法仍在运行(只要从当前执行状态下无法访问Bar),也可以收集Bar。@Porges-通过“仍然存在”,我的意思是Foo是可访问的(有人引用它,使它保持活动状态)。您能否解释一下“即使对象无法访问,实例成员也可以运行”的情况?什么时候会发生这种情况?如果(通过代码检查)您会说Foo是可访问的-但是优化器可能能够确定对象只被设置了,并且不再被访问。那么该物品是否会被处置?