Joh*_*ohn 184 .net c# vb.net null memory-management
完成后,是否应该将所有对象设置为null(Nothing在VB.NET中)?
我理解在.NET中必须处理实现IDisposable接口的任何对象实例以释放一些资源,尽管对象在处理之后仍然可以是某种东西(因此isDisposed表单中的属性),所以我认为它仍然可以驻留在记忆中还是至少部分?
我也知道当一个对象超出范围时,它会被标记为收集准备好下一次垃圾收集器的传递(虽然这可能需要时间).
因此,考虑到这一点,将其设置为null加速系统释放内存,因为它不必解决它不再在范围内并且它们是否有任何不良副作用?
MSDN文章从未在示例中执行此操作,目前我这样做是因为我无法看到它的危害.但是我遇到了各种意见,所以任何评论都是有用的.
Kev*_*Kev 71
Karl绝对正确,使用后无需将对象设置为null.如果一个对象实现了IDisposable,只要确保IDisposable.Dispose()在完成该对象时调用(包装在try.. finally,或者一个using()块中).但即使你不记得打电话Dispose(),对象的终结者方法应该是Dispose()你.
我认为这是一个很好的待遇:
还有这个
尝试再次猜测GC及其管理策略没有任何意义,因为它是自我调整和不透明的.关于Jeffrey Richter在Dot Net Rocks上的内部运作有一个很好的讨论:Jeff Memory Rich 在Windows内存模型和Richters的书中通过C#第20章预订CLR有一个很好的处理:
Wil*_*lka 36
避免在完成对象时将对象设置为null的另一个原因是它实际上可以使它们保持活动更长时间.
例如
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is now eligible for garbage collection
// ... rest of method not using 'someType' ...
}
Run Code Online (Sandbox Code Playgroud)
在调用"DoSomething"之后,允许someType引用的对象为GC'd
void foo()
{
var someType = new SomeType();
someType.DoSomething();
// someType is NOT eligible for garbage collection yet
// because that variable is used at the end of the method
// ... rest of method not using 'someType' ...
someType = null;
}
Run Code Online (Sandbox Code Playgroud)
有时可能会保持对象存活直到方法结束.在JIT通常会优化掉分配为空的,所以码两个位最终是相同的.
Kar*_*uin 14
不要没有null对象.你可以查看http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx获取更多信息,但设置的东西除了脏代码之外,null将不会执行任何操作.
也:
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
Run Code Online (Sandbox Code Playgroud)
一般来说,使用后不需要空对象,但在某些情况下我发现这是一个很好的做法.
如果一个对象实现了IDisposable并存储在一个字段中,我认为将其置零是好的,只是为了避免使用被处置的对象.以下类型的错误可能会很痛苦:
this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();
Run Code Online (Sandbox Code Playgroud)
在处理之后将字段置零是很好的,并且在再次使用该字段的行处获得NullPtrEx.否则,你可能会遇到一些神秘的错误(具体取决于DoSomething的作用).
如果您觉得需要null变量,那么您的代码可能不够紧密.
有许多方法可以限制变量的范围:
正如Steve Tranby所说
using(SomeObject object = new SomeObject())
{
// do stuff with the object
}
// the object will be disposed of
Run Code Online (Sandbox Code Playgroud)
同样,您可以简单地使用花括号:
{
// Declare the variable and use it
SomeObject object = new SomeObject()
}
// The variable is no longer available
Run Code Online (Sandbox Code Playgroud)
我发现使用没有任何"标题"的大括号来真正清理代码并使其更容易理解.
您应该将变量设置为null的唯一时间是变量不超出范围并且您不再需要与其关联的数据.否则就没有必要了.
通常不需要设置为null.但假设您的班级中有重置功能.
然后你可能会这样做,因为你不想两次调用dispose,因为某些Dispose可能无法正确实现并抛出System.ObjectDisposed异常.
private void Reset()
{
if(_dataset != null)
{
_dataset.Dispose();
_dataset = null;
}
//..More such member variables like oracle connection etc. _oraConnection
}
Run Code Online (Sandbox Code Playgroud)