我们知道.Net
中对于内存的管理有两种方式,一种是托管对象管理,另一种是非托管对象管理。而我们通常理解的内存管理就是GC
(垃圾收集),虽然GC
通过对托管堆的管理,可以使我们有机会从繁锁的诸如内存泄漏之类的问题中解放出来,可以将精力专注于程序的逻辑上。但是将所有的事情都交给GC
有时会损及程序的效率,严重的甚至会导致错误。
为什么会出现这种情况呢?问题在于对非托管资源(文件句柄)或者需要特别关照的对象(Bitmap
)对象等,GC
表现得就有点差强人意了(这句话或许说得并不正确,因为微软设计GC
的本意就是用来针对托管对象管理)。如何有效地利用GC
来进行内存管理,如何对程序的性能进行优化不是本文讨论的范围。本文的要旨在于AE
开发中如何来释放非托管对象。
一、AOUninitialize.Shutdown.
很多时候我们都会遇到这种情况:在退出AE应用程序中,常常提示这样的错误:“
The
instruction x references memory at x. The memory could not be read
”。出现这种错误的原因主要在于
COM
对象(非托管对象)没有释放,在我们结束使用它的进程的时候,它阻止我们正常释放它,它释放的优先级高于当前使用它的进程释放的优先级,也就是说进程释放之前,必须先释放掉它。
明白了上面的原理,那么解决这一问题的方法便非常简单,我们只需在应用程序退出之前调用ESRI.ArcGIS.ADF.COMSupport.AOUninitialize.Shutdown()方法即可释放非托管对象了(9.2之前的版本AoUninitialize并不在ESRI.ArcGIS.ADF.COMSupport命名空间下,需注意)。
二、Marshal.ReleaseComObject
NET
开发中,引用COM对象主要是通过RCW(Runtime Callable Wrappers)机制来实现的(有点类似于代理模式)。对于COM对象的释放,GC表现得有点无能为力,因此必须在程序中显示释放掉COM对象占用的资源,否则将会出现一些意想不到的错误。比如重复地从Personal GeoDataBase中打开GeoDataBase Cursors而又没有及时释放,将会引发“No more tables can be opened.”其它情形中,你可能会发现应用程序退出时,COM对象依然在内存中引用。比如StyleGallery如果没有显示释放,在应用程序退出时就会引发错误。
1
、Releasing StyleGallery:
private void
MyFunction()
{
IStyleGallery styCls =
new
StyleGalleryClass()
as
IStyleGallery;