释放Arcgis内存

  • 格式:doc
  • 大小:37.00 KB
  • 文档页数:3

下载文档原格式

  / 6
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

.NET+AE开发中常见几种非托管对象的释放

我们知道.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 对象(非托管对象)没有释放,在我们结束使用它的进程的时候,它阻止我们正常释放它,它释放的优先级高于当前使用它的进程释放的优先级,也就是说进程释放之前,必须先释放掉它。

明白了上面的原理,那么解决这一问题的方法便非常简单,我们只需在应用程序退出之前调用Support.AOUninitialize.Shutdown()方法即可释放非托管对象了(9.2之前的版本AoUninitialize并不在Support命名空间下,需注意)。

二、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;

// Use the StyleGalleryClass here ...

int

refsLeft = 0;

do { refsLeft =

Marshal

.ReleaseComObject(styCls); }

while

(refsLeft > 0); }2 、Releasing geodatabase cursors

for ( int i = 1; i < 2500; i++)

{ IQueryFilter qu = New QueryFilterClass(); qu.WhereClause = @"Area = " + i.ToString(); IFeatureCursor featCursor = featClass.Search(qu, true

);

// Use the feature cursor as required System.Runtime.InteropServices.

Marshal

.ReleaseComObject(featCursor); }3 、Releasing WebObject(ArcGIS Server)

private void

doSomthing_Click(

object

sender, System.EventArgs e) {

using

(WebObject webobj =

new

WebObject()) { ServerConnection serverConn =

new

ServerConnection("doug",

true

); IServerObjectManager som = serverConn.ServerObjectManager; IServerContext ctx = som.CreateServerContext("Yellowstone","MapServer"); IMapServer mapsrv = ctx.ServerObject

as

IMapServer; IMapServerObjects mapo = mapsrv

as

IMapServerObjects; IMap map = mapo.get_Map(mapsrv.DefaultMapName); IFeatureLayer flayer = map.get_Layer(0)

as

IFeatureLayer; IFeatureClass fclass = flayer.FeatureClass; IFeatureCursor fcursor = fclass.Search(

null

,

true

); webobj.ManageLifetime(fcursor); IFeature f = null;

while

((f = fcursor.NextFeature()) !=

null

) {

// do something with the feature

} ctx.ReleaseContext(); } }三、什么时候应该释放非托管对象?

这个问题非常重要,当我们确信在释放之后不再调用非托管对象资源时候,就可以调用System.Runtime.InteropServices. Marshal.ReleaseComObject ()方法进行显式释放了,否则将会引发新的错误。

总结:本文简单的列举了AE 开发中几种常见非托管对象的释放问题,以供大家参考。有些方面说得不够详细,大家可以从ArcGIS Engine 帮助中求得详细资料。