vb.net虚拟内存 visual studio调整虚拟内存( 九 )


·GDI对象 支持图形绘制:位图(bitmaps),笔刷(Brushes),设备上下文(DC),字体(Fonts),内存设置上下文(Memory DCs),元文件(Metafiles),画笔(Pens),区域(Regions)等 。
·内核对象 支持内存管理,进程执行和进程间通讯(IPC):文件,进程 , 线程,信号(Semaphores),定时器(Timer),访问记号(Access tokens),套接字(Sockets)等 。
所有系统对象的详细情况都可以在MSDN中找到 。
系统对象之外 , 你还会碰到句柄(handles).据MSDN的陈述,应用程序不能直接访问对象数据或是对象所代表的系统资源 。取而代之,应用程序一定都会获得一个对象句柄(Handle),可以使用它检查或是修改系统资源 。在.net中无论如何,多数情况下系统资源的使用都是透明的,因为系统对象与句柄都由.net类直接或间接代表了 。
非托管资源
像系统对象(System objects)这样的资源自身都不是个问题,但本文仍涵盖了它们,因为像Windows这样的操作系统对可同时打开的 套接字、文件等的数量都有限制 。所以关注应用程序所使用系统对象的数量非常重要 。
在特定时间段内一个进程所能使用的User与GDI对象数目也是有配额的 。缺省值是10000个GDI对象和10000个User对象 。如果想知道本机的相关设置值,可以使用如下的注册表键:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows: GDIProcessHandleQuota 和 USERProcessHandleQuota.
猜到了什么?确实没有这么简单,还有一些你会很快达到的其它限制 。比如参照:我的一篇有关桌面堆的博客 所述 。
假设这些值是可以自定义的 , 你也许认为一个解决方案就是打破默认值的限制—调高这些配额 。但我认为这可不是个好主意,有如下原因:
1. 配额存在的原因:系统中不是只有你独自一个应用程序,所有运行在计算机中的其它进程与你的应用应该分享系统资源 。
2.如果你修改配额,使它不同于其它系统了 。你不得不确认所有你的应用程序需要运行的机器都完成了这样的修改,而且这样的修改从系统管理员的角度来说是否会有问题也需要确认 。
3.大部分都采用了默认配额值 。如果你发现配置值对你应用程序来说不够,那你可能确实有些清理工作要做了 。
如何检测泄露及找到泄露的资源
泄露带来的实际问题在MSDN上的一篇文章中有着很好的描述:
哪怕在小的泄露只要它反复出现也会拖垮系统 。
这与水的泄露异曲同工 。一滴水的落下不是什么大问题 。但是一滴一滴如此反复的泄露也会变为一个大问题 。
像我稍后解释的,一个无意义的对象可以在内存中维持一整图的重量级对象 。
仍然是同一篇文章,你会了解到:
通常三步根除泄露:
1.发现泄露
2.找到被泄露的资源
3.决定在源码中何时何处释放该资源
最直接“发现”泄露的方式是遭受泄露引发的问题
你或许没有见过内存不足 。“内存不足”提示信息极少出现 。因为操作系统运行中实际内存(RAM)不足时,它会使用硬盘空间来扩展内存 。(称为虚拟内存) 。
在你的图形应用程序中可能更多出现的是“句柄不足”的异常 。准确的异常不是System.ComponentModel.Win32Exception 就是 System.OutOfMemoryException 均包含如下信息:”创建窗体句柄错误” 。这两个异常多发于两个资源被同时使用的情况下,通常都因为该释放的对象没有被释放所致 。
另外一种你会经常碰到的情况是你的应用程序或是整个系统变更得越来越慢 。这种情况的发生是因为你的系统资源即将耗尽 。
我来做个生硬的推断:大多数应用程序的泄露在多数时间里都不是个问题,因为由泄露导致出现的问题只在你的应用程序集中使用很长时间的情况下才会出现 。

推荐阅读