我有一个奇怪的现象,一直在实例化一个com-wrapper,然后让GC收集它(不强制)。
我正在WinCE x86上测试.net cf。使用.net Compact框架远程监视器监视性能。使用平台构建器工具包中的Windows CE远程性能监视器跟踪本机内存。
在前1000个创建的实例中,perfmon中的每个计数器似乎都可以:
然而,在那些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);
}
}
答案 0 :(得分:4)
嗯,您的代码中存在一个错误,即您正在创建大量IDisposable实例,并且从不在它们上调用Dispose。我希望终结者最终能够进入,但他们不应该真的有必要。在您的生产代码中,您是否妥善处理了所有内容 - 如果没有,是否有某些原因导致您无法处理?
如果你在AlphaImage终结器中放入一些日志记录(检测到AppDomain卸载和应用程序关闭而不记录这些情况!)它是否显示正在调用终结器?
编辑:一个潜在的问题,可能不是咬你,但无论如何都可能值得修复 - 如果对CreateImageFromBuffer的调用因任何原因失败,你仍然拥有AllocHGlobal创建的内存,并且目前将被泄露。我怀疑这不是问题,或者它会更加壮观,但是值得考虑。答案 1 :(得分:3)
我怀疑这是RPM的一个错误。我们这里没有的是对Ppb.Drawing东西的任何见解。我看到潜在问题的地方是GetIImagingFactory调用。它有什么作用?它可能只是一个单身的吸气剂,但这是我追逐的东西。
我也看到了AllochHGlobal,但我没有看到该分配被释放。现在,这是我关注的地方。