我正在开发mono和.net应用程序。我对最佳实践有一些基本问题。
如果我需要创建一个非托管对象只是为了使用一次(可能会传递给方法或调用其中一种方法)并且以后不需要它,我应该分配它先变量变量然后使用它以便我可以处理它(或者可以在using()
块中赋值变量)或者我应该使用类似new Class().Method()
的变量,以便GC能够收集它?什么是最佳做法?
我是否需要处理只有方法的局部范围的对象,或者如果我处理属于该类属性的对象(全局),是否足够?
我有一个A类和一个B类.B的一个对象是在A类的某个方法M中创建的。这个对象(B类)有另一个方法M2,它调用A类中的第二个方法, M3。所以结构如下
Class A
{
void M()
{
var b = new B();
}
public string M3()
{
return "OK";
}
}
Class B
{
void M2()
{
Console.WriteLine(new A().M3();
}
}
这会创建一个循环引用来阻止GC收集这两个对象吗?
良好的内存有效编程的其他一般原则是什么?
答案 0 :(得分:2)
这个问题具有变得“过于宽泛”的重大风险,即StackOverflow的偏离主题。也就是说,一些简要回答:
- 如果我需要创建一个非托管对象只是为了使用一次(可能会传递给方法或调用其中一种方法)而以后不需要它......最佳实践是什么?
醇>
使用任何非托管对象的最佳做法是将其包装在SafeHandle
的实例中。当然,您必须处理的大多数常见非托管对象已经由.NET包装,可以在IDisposable
的某些自定义实现中(例如StreamReader
),也可以在更新的框架代码中,作为{ {1}}子类。
但是当你处理.NET不知道的你自己的非托管对象时,你会想要遵循.NET的例子并使用SafeHandle
。
- 我是否需要处理只有方法的局部范围的对象,或者如果我处理属于该类属性的对象(全局),是否足够?
醇>
如果您创建了对象,并且尚未将其传递给其他代码以供其拥有,并且您不打算从该方法返回它,那么您需要将其处理掉。 do 需要处理仅在方法中引用的对象。
通常,您可以使用SafeHandle
语句执行此操作。
- ...这会创建一个循环引用,停止GC收集这两个对象吗?
醇>
忽略您的代码示例无法编译,也不包含任何引用循环......:)
与某些内存管理方案(例如引用计数)不同,.NET的垃圾回收根本没有任何循环引用问题。根据是否可以从 root 引用访问对象,确定该对象是否可收集。
表示两个无法引用的对象相互引用仍然无法从根引用中访问。良好的内存有效编程的其他一般原则是什么?
这对于StackOverflow来说肯定太宽泛了。即使在.NET使用的基于GC的系统中,也有许多人可以关注的细节。基本系统消除了许多常见的编程错误,但它有自己的特殊行为,在某些情况下很难理解。
花一些时间浏览关于该主题的MSDN和网络文章将有助于您在.NET和一般情况下了解有关垃圾收集的更多信息。如果您有其他特定的问题,请随时在StackOverflow上发布。