ESRI Desteği, sorunu yeniden oluşturduklarını ve bir hata raporu açtıklarını söylüyor (NIM070156).
Benim .NET / C # ArcMap eklenti bir araç ( bir sorgu filtresi ile ICursor
gelen dönen) bir uzamsal sorgu gerçekleştirdiğinde oluşan bir bellek sızıntısı (yönetilmeyen yığın bellek) olduğunu belirledim . Tüm COM nesneleri artık gerekli olmadıkları anda serbest bırakılıyor (kullanılıyor ).IFeatureClass.Search
ISpatialFilter
Marshal.FinalReleaseCOMObject
Bunu belirlemek için önce ArcMap.exe'nin Özel Baytları, Sanal Baytlar ve Çalışma Kümesi için sayaçlarla bir PerfMon oturumu kurdum ve üçünü de sorguyu gerçekleştiren aracın her kullanımıyla birlikte sürekli olarak arttı (kabaca 500 KB). . Bu, yalnızca doğrudan bağlantı (ST_Geometry depolama, Oracle 11g istemci ve sunucu) kullanılarak SDE'deki özellik sınıflarına karşı gerçekleştirildiğinde gerçekleşir . Sayaçlar, bir dosya coğrafi veritabanı kullanılırken ve ayrıca uygulama bağlantısı kullanan eski bir SDE örneğine bağlanırken sabit kaldı.
Daha sonra LeakDiag ve LDGrapher kullandım (bu blog gönderisinden bazı rehberlikle ) ve Windows Yığın Allocator'u üç kez kaydettim: ArcMap'ı ilk yüklediğimde ve aracı başlatmak için aracı birkaç düzine çalıştırdıktan sonra ve çalıştırdıktan sonra birkaç düzine kez daha.
LDGrapher'in varsayılan görünümünde (toplam boyut) gösterilen sonuçlar şunlardır:
İşte kırmızı hat için çağrı yığını:
Gördüğünüz gibi SgsShapeFindRelation2
sg.dll işlevi bellek sızıntısından sorumlu gibi görünüyor.
Anladığım kadarıyla sg.dll ArcObjects tarafından kullanılan çekirdek geometri kütüphanesi ve SgsShapeFindRelation2
muhtemelen mekansal filtre uygulandığı yerdir.
Başka bir şey yapmadan önce, başka birinin bu sorunla (veya benzer bir şeyle) karşılaşıp karşılaşmadığını ve bu konuda yapabildikleri herhangi bir şey olup olmadığını görmek istedim. Ayrıca, bunun yalnızca doğrudan bağlantıda gerçekleşmesinin nedeni ne olabilir? ArcObjects'teki bir hata, bir yapılandırma sorunu veya bir programlama sorunu gibi görünüyor mu?
İşte bu davranışı üreten yöntemin en az çalışan bir sürümü:
private string GetValueAtPoint(IPoint pPoint, IFeatureClass pFeatureClass, string pFieldName)
{
string results = "";
ISpatialFilter pSpatialFilter = null;
ICursor pCursor = null;
IRow pRow = null;
try
{
pSpatialFilter = new SpatialFilterClass();
pSpatialFilter.Geometry = pPoint;
pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
pSpatialFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
pCursor = (ICursor)pFeatureClass.Search(pSpatialFilter, false);
pRow = pCursor.NextRow();
if (pRow != null)
results = pRow.get_Value(pFeatureClass.FindField(pFieldName)).ToString();
}
finally
{
// Explicitly release COM objects
if (pRow != null)
Marshal.FinalReleaseComObject(pRow);
if (pCursor != null)
Marshal.FinalReleaseComObject(pCursor);
if (pSpatialFilter != null)
Marshal.FinalReleaseComObject(pSpatialFilter);
}
return results;
}
İşte Ragi ile ilgili tartışmaya dayanan geçici çözüm kodum:
private bool PointIntersectsFeature(IPoint pPoint, IFeature pFeature)
{
bool returnVal = false;
ITopologicalOperator pTopoOp = null;
IGeometry pGeom = null;
try
{
pTopoOp = ((IClone)pPoint).Clone() as ITopologicalOperator;
if (pTopoOp != null)
{
pGeom = pTopoOp.Intersect(pFeature.Shape, esriGeometryDimension.esriGeometry0Dimension);
if (pGeom != null && !(pGeom.IsEmpty))
returnVal = true;
}
}
finally
{
// Explicitly release COM objects
if (pGeom != null)
Marshal.FinalReleaseComObject(pGeom);
if (pTopoOp != null)
Marshal.FinalReleaseComObject(pTopoOp);
}
return returnVal;
}
private string GetValueAtPoint(IPoint pPoint, IFeatureClass pFeatureClass, string pFieldName)
{
string results = "";
ISpatialFilter pSpatialFilter = null;
IFeatureCursor pFeatureCursor = null;
IFeature pFeature = null;
try
{
pSpatialFilter = new SpatialFilterClass();
pSpatialFilter.Geometry = pPoint;
pSpatialFilter.GeometryField = pFeatureClass.ShapeFieldName;
pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelEnvelopeIntersects;
pFeatureCursor = pFeatureClass.Search(pSpatialFilter, true);
pFeature = pFeatureCursor.NextFeature();
while (pFeature != null)
{
if (PointIntersectsFeature(pPoint, pFeature))
{
results = pFeature.get_Value(pFeatureClass.FindField(pFieldName)).ToString();
break;
}
pFeature = pFeatureCursor.NextFeature();
}
}
finally
{
// Explicitly release COM objects
if (pFeature != null)
Marshal.FinalReleaseComObject(pFeature);
if (pFeatureCursor != null)
Marshal.FinalReleaseComObject(pFeatureCursor);
if (pSpatialFilter != null)
Marshal.FinalReleaseComObject(pSpatialFilter);
}
return results;
}