在連續實例化一個com-wrapper並讓GC收集它(不是強制)的同時,我有一個奇怪的現象。GC在一段時間後包含大量固定對象
我在WinCE x86上測試.net cf。使用.net Compact框架遠程監視器監視性能。使用平臺構建器工具包中的Windows CE Remote性能監視器跟蹤本機內存。
在第一個1000創建的實例在性能監視器每個櫃檯似乎確定:
- GC堆上升和下降,但平均保持不變
- 固定的對象是0
- 本機內存保持相同的平均
- ...
然而,經過這些1000(大約)針扎對象計數器只升不計在以後再下降。但內存使用情況保持不變。
我不知道從這些信息中得出什麼結論......這是計數器中的錯誤,這是我軟件中的錯誤嗎?
[編輯]
我也注意到,固定的對象計數器開始儘快上去的總字節數在使用GC穩定後,如不通過壓實機櫃臺移動的物體。
The graphic of the counters http://files.stormenet.be/gc_pinnedobj.jpg
[/編輯]
這裏涉及的代碼:
private void pButton6_Click(object sender, EventArgs e) {
if (_running) {
_running = false;
return;
}
_loopcount = 0;
_running = true;
Thread d = new Thread(new ThreadStart(LoopRun));
d.Start();
}
private void LoopRun() {
while (_running) {
CreateInstances();
_loopcount++;
RefreshLabel();
}
}
void CreateInstances() {
List<Ppb.Drawing.Image> list = new List<Ppb.Drawing.Image>();
for (int i = 0; i < 10; i++) {
Ppb.Drawing.Image g = resourcesObj.someBitmap;
list.Add(g);
}
}
Image對象包含一個AlphaImage:
public sealed class AlphaImage : IDisposable {
IImage _image;
Size _size;
IntPtr _bufferPtr;
public static AlphaImage CreateFromBuffer(byte[] buffer, long size) {
AlphaImage instance = new AlphaImage();
IImage img;
instance._bufferPtr = Marshal.AllocHGlobal((int)size);
Marshal.Copy(buffer, 0, instance._bufferPtr, (int)size);
GetIImagingFactory().CreateImageFromBuffer(instance._bufferPtr, (uint)size, BufferDisposalFlag.BufferDisposalFlagGlobalFree, out img);
instance.SetImage(img);
return instance;
}
void SetImage(IImage image) {
_image = image;
ImageInfo imgInfo;
_image.GetImageInfo(out imgInfo);
_size = new Size((int)imgInfo.Width, (int)imgInfo.Height);
}
~AlphaImage() {
Dispose();
}
#region IDisposable Members
public void Dispose() {
Marshal.FinalReleaseComObject(_image);
}
}
正在調用終結器(如果它不會在幾秒鐘內失效)。 實際上,在調用AlphaImage Dispose的AlphaImage類中有一個Image類包裝器。 – Stormenet 2008-12-17 11:38:13
不過,你不應該指望終結者 - 這是IDisposable的用途。 您應該使用using(image){...}構造來確保儘快調用Dispose方法。此外,在Dispose()中使用GC.SuppressFinalize(),以便終止對象不會被調用。 – configurator 2008-12-17 13:00:38