就在最近,我的一些同事帮助缩小了内存泄漏。其中一个问题是在微软的代码中找到的。这是来自反射器,表明枚举器会泄漏。
这里count属性调用getenumerator但从不检查Idisposable:
public int Count
{
get
{
if (this.isDisposed)
{
throw new ObjectDisposedException(name);
}
int num = 0;
IEnumerator enumerator = this.GetEnumerator();
while (enumerator.MoveNext())
{
num++;
}
return num;
}
}
这是ManagementObjectCollection的GetEnumerator,只是为了显示返回的类型是ManagementObjectEnumerator。
public ManagementObjectEnumerator GetEnumerator()
{
if (this.isDisposed)
{
throw new ObjectDisposedException(name);
}
if (!this.options.Rewindable)
{
return new ManagementObjectEnumerator(this, this.enumWbem);
}
IEnumWbemClassObject ppEnum = null;
int errorCode = 0;
try
{
errorCode = this.scope.GetSecuredIEnumWbemClassObjectHandler(this.enumWbem).Clone_(ref ppEnum);
if ((errorCode & 0x80000000L) == 0L)
{
errorCode = this.scope.GetSecuredIEnumWbemClassObjectHandler(ppEnum).Reset_();
}
}
catch (COMException exception)
{
ManagementException.ThrowWithExtendedInfo(exception);
}
if ((errorCode & 0xfffff000L) == 0x80041000L)
{
ManagementException.ThrowWithExtendedInfo((ManagementStatus) errorCode);
}
else if ((errorCode & 0x80000000L) != 0L)
{
Marshal.ThrowExceptionForHR(errorCode);
}
return new ManagementObjectEnumerator(this, ppEnum);
}
这表明它是一次性的:
public class ManagementObjectEnumerator : IEnumerator, IDisposable
{
// Fields
private bool atEndOfCollection;
private uint cachedCount;
private IWbemClassObjectFreeThreaded[] cachedObjects;
private int cacheIndex;
private ManagementObjectCollection collectionObject;
private IEnumWbemClassObject enumWbem;
private bool isDisposed;
private static readonly string name;
// Methods
static ManagementObjectEnumerator();
internal ManagementObjectEnumerator(ManagementObjectCollection collectionObject, IEnumWbemClassObject enumWbem);
public void Dispose();
protected override void Finalize();
public bool MoveNext();
public void Reset();
// Properties
public ManagementBaseObject Current { get; }
object IEnumerator.Current { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
}
虽然一次性的调查员通过foreach语句(http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx)正确处理,但这并不意味着仅使用枚举器的情况是在foreach循环中。
我知道您可以跳过count属性并使用自己的枚举器来推送自己的机制来获取集合中的对象数量,但我的问题是这个泄漏会导致多少非托管内存?