我的程序中有一个错误,所以我做了一些实验,发现以下代码结束了
运行一段时间后抛出异常。
while ( 1 )
{
System::Drawing::Bitmap^ pBitmap = gcnew System::Drawing::Bitmap( 500, 500 );
this->Cursor = gcnew System::Windows::Forms::Cursor(pBitmap->GetHicon());
}
我无法找到该异常的任何线索。
怎么了?
所以我将代码更改为
while ( 1 )
{
System::Drawing::Bitmap^ pBitmap = gcnew System::Drawing::Bitmap(500,500);
System::Windows::Forms::Cursor^ pCursor = gcnew System::Windows::Forms::Cursor(pBitmap->GetHicon());
delete pBitmap;
delete pCursor;
}
同样的异常仍然被抛出。
任何线索都会感激不尽。
答案 0 :(得分:2)
创建位图时,请求内存(500 * 500 * bytesPerPixeL)和内部GDI句柄。可用句柄的数量非常大,但有限。所以,我的猜测是你要么在垃圾收集器启动之前耗尽内存,要么用完GDI句柄。
你应该使用(pBitmap = ...)来自动调用Dispose()或在你完成后手动调用Dispose()。 Cursor也一样。
MSDN文章GDI Objects说:
“每个会话的理论限制为65,536个GDI句柄。但是,每个会话可以打开的最大GDI句柄数通常较低,因为它受可用内存的影响。”
答案 1 :(得分:0)
我重新创建了问题,它看起来像这样: Screenshot
当我查看任务管理器时,在运行前5000次运行程序时我的内存消耗看起来像我预期的那样。图形在为新图像分配内存时增长,在GC释放内存时减少 - 但是,释放内存似乎永远不会是完美的,因为它在降低期间降低的值不断上升。这让我相信你有某种记忆漏洞。
- 所以,我的夏洛克福尔摩斯的技能变成了一种骚动,我的Columbo技能接管了。什么可能导致这样的泄漏?嗯..忘了打电话.Dispose()?是的,Bitmap确实实现了IDisposable,sooo,你应该记得在创建新的位图之前在你的位图上调用.Dispose():)