.NET+AE 개발에서 흔히 볼 수 있는 몇 가지 비위탁 관리 대상의 방출

13348 단어 net
우리는 알고 있소.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 대상(비위탁 관리 대상)이 방출되지 않았기 때문이다. 우리가 프로세스를 사용했을 때 정상적으로 방출되는 것을 막는다. COM 대상의 방출 우선순위는 현재 사용한 프로세스의 방출 우선순위보다 높다. 즉, 프로세스가 방출되기 전에 반드시 방출해야 한다.
위의 원리를 이해하면 이 문제를 해결하는 방법은 매우 간단하다. 우리는 프로그램이 종료되기 전에 ESRI를 호출하기만 하면 된다.ArcGIS.ADF.COMSupport.AOUninitialize.Shutdown () 방법은 비위탁 관리 대상을 방출할 수 있습니다. (9.2 이전 버전의 AoUnininitialize는 ESRI.ArcGIS.ADF.COMsupport 명칭 공간에 있지 않습니다. 주의해야 합니다.)
2. 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);
  }

3Releasing 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

1、 얘기 좀 하자.NET의 메모리 관리 

2、 ArcGIS Engine

 :http://www.cnblogs.com/3echo/archive/2008/04/20/1162304.html

좋은 웹페이지 즐겨찾기