7

Can anyone else reproduce the memory leak described below? Any insight into what may be causing the leak is appreciated.

I have custom code that swaps between landscape and portrait templates and exports a large number of maps to PDF. Unfortunately, there is a memory leak occurring when I swap from template to template that eventually causes the ArcMap to crash.

I can reproduce the memory leak using the Minerville data and workflow described below.

Configuration:

ArcFM Solution Desktop 10.1

ArcGIS 10.1 for Desktop 10.1

Windows 7 64-bit or Windows XP 32-bit or Windows 2008 64-bit

Workflow:

1) Open Minerville database in ArcMap

2) Open “Stored Items” dropdown

3) Select “Page Templates” tab

4) Double-click the “Adjacent Grids” template to load it

5) Repeat steps 2-3 and double-click “Designer Detail Map Sheet”

6) Repeat steps 2 – 5 and watch memory usage climb in task manager

Using UMDH, the largest ArcFM-related offenders seem to be these:

Stack #1:

ntdll!RtlAllocateHeap+00000274
KERNELBASE!LocalAlloc+0000005F
GDI32!pmfAllocMF+0000018C
GDI32!SetEnhMetaFileBits+00000033
OLEAUT32!_PictLoadUnknownMetaFile+00000088
OLEAUT32!_PictLoadNewImage+000001A0
OLEAUT32!_PictLoadPicture+00000025
OLEAUT32!CPicture::Load+00000027
SystemCore!ObjectStream::LoadObject+000003E9
AfCore!LoadObject+0000005E
RasterGraphicElements!BasePictureElement::Load+000000ED
SystemCore!ObjectStream::LoadObject+000003E9
AfCore!LoadObject+0000005E
AfCore!ExtraSafeReadObject+00000072
PageLayout!PageLayout::Load+00000174
SystemCore!ObjectStream::LoadObject+000003E9
MMStoredStuff!DllGetClassesForCategoryReg+00011B32
MMStoredStuff!???+00000000 : 2DB04186
MMStoredStuff!DllGetClassesForCategoryReg+0000D9E5
MMStoredStuff!DllGetClassesForCategoryReg+0000C297
mmPageTemplatesUI!DllCanUnloadNow+00020402
mmPageTemplatesUI!DllCanUnloadNow+00038EAF
mmFrameworkListObjects!DllGetClassesAndCategories+000C38DC
mscorwks!CLRToCOMWorker+0000019A

Stack #2:

ntdll!RtlAllocateHeap+00000274
MSVCR90!malloc+00000079
MSVCR90!operator new+0000001F
DisplayCore!ClassFactory<CartographicLineSymbol>::CreateInstance+000000D8
AfCore!FactoryCache::CreateInstance+00000095
AfCore!FactoryCacheDispatcher::CreateInstance+00000050
AfCore!AfCreateInstance+00000040
SystemCore!ObjectStream::LoadObject+00000297
AfCore!LoadObject+0000005E
DisplayCore!MultiLayerLineSymbol::Load+000000F8
SystemCore!ObjectStream::LoadObject+000003E9
AfCore!LoadObject+0000005E
GraphicElements!LineElement::Load+00000076
SystemCore!ObjectStream::LoadObject+000003E9
AfCore!LoadObject+0000005E
GraphicElements!GroupElement::Load+00000082
SystemCore!ObjectStream::LoadObject+000003E9
AfCore!LoadObject+0000005E
AfCore!ExtraSafeReadObject+00000072
PageLayout!PageLayout::Load+00000174
SystemCore!ObjectStream::LoadObject+000003E9
MMStoredStuff!DllGetClassesForCategoryReg+00011B32
MMStoredStuff!???+00000000 : 2DB04186
MMStoredStuff!DllGetClassesForCategoryReg+0000D9E5
MMStoredStuff!DllGetClassesForCategoryReg+0000C297
mmPageTemplatesUI!DllCanUnloadNow+00020402
mmPageTemplatesUI!DllCanUnloadNow+00038EAF
mmFrameworkListObjects!DllGetClassesAndCategories+000C38DC
mscorwks!CLRToCOMWorker+0000019A

UPDATE #1:

Schneider Electric's support was able to reproduce the problem and has created a bug. I was told that if a fix was made at all, it would not be available until the 10.2 release.

I'll post more as I get more information.

2
  • 1
    +1 for showing usefulness of UMDH. Commented Mar 21, 2013 at 14:21
  • I hate to be snarky, but why not both?
    – D.E.Wright
    Commented Sep 19, 2014 at 19:06

1 Answer 1

2

I also face similar situation when i was updating entire feature class and i notice that arcFM autoupdators causing the memory leak.

while ((fcDeviceGroup = featureCursor.NextFeature()) != null)
                        {
                            long mem1 = GC.GetTotalMemory(true);
                            _log.Debug("Memory Before " + mem1);
                            Debug.Print("Memory Before {0}", mem1);                          
                            processed++;
                            Console.WriteLine("Processing " + processed + " in total features: " + count);
                            if (!indexStrc)
                            {
                                structureGuid = fcDeviceGroup.Fields.FindField("globalid");
                            }
                            STRUCTUREGUID = Convert.ToString(fcDeviceGroup.get_Value(structureGuid));
                            GetOpenPointDictionary(STRUCTUREGUID, openPoint, checkStatus, busBar, ref indexSet, ref indexOpVolt);
                            Marshal.FinalReleaseComObject(fcDeviceGroup);
                            long mem2 = GC.GetTotalMemory(true);
                            Debug.Print("Memory After {0}", mem2);
                            Debug.Print("Difference {0}", mem1 - mem2);
                            _log.Debug("Memory After " + mem2);
                            _log.Debug("Difference " + Convert.ToString(mem1 - mem2));
                        }
                        if (featureCursor != null)
                        {
                            while (Marshal.FinalReleaseComObject(featureCursor) > 0) { }
                        }

This is code i was using to check for memory leak. When autoupdors was enable then every iteration memory sampling was.
2014-09-19 10:28:02,764 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 863664
2014-09-19 10:28:02,764 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:02,777 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 863804
2014-09-19 10:28:03,532 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864196
2014-09-19 10:28:03,936 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory Update Operation****************** 864508
2014-09-19 10:28:03,938 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - ****************Difference 312
2014-09-19 10:28:03,946 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 863940
2014-09-19 10:28:03,946 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference -136
2014-09-19 10:28:03,962 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 863920
2014-09-19 10:28:04,180 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 863960
2014-09-19 10:28:04,199 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 863876
2014-09-19 10:28:04,200 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 44
2014-09-19 10:28:04,212 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864016
2014-09-19 10:28:04,702 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864348
2014-09-19 10:28:05,052 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory Update Operation****************** 864656
2014-09-19 10:28:05,055 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - ****************Difference 308
2014-09-19 10:28:05,063 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864156
2014-09-19 10:28:05,063 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference -140
2014-09-19 10:28:05,070 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864136
2014-09-19 10:28:05,957 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864624
2014-09-19 10:28:06,287 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory Update Operation****************** 864936
2014-09-19 10:28:06,288 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - ****************Difference 312
2014-09-19 10:28:06,291 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864376
2014-09-19 10:28:06,291 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference -240
2014-09-19 10:28:06,300 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864356
2014-09-19 10:28:07,129 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864960
2014-09-19 10:28:07,585 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory Update Operation****************** 865272
2014-09-19 10:28:07,588 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - ****************Difference 312
2014-09-19 10:28:07,594 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864588
2014-09-19 10:28:07,595 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference -232
2014-09-19 10:28:07,613 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864568
2014-09-19 10:28:07,843 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:07,865 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:07,866 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 44
2014-09-19 10:28:07,878 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:07,968 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:07,990 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:07,991 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,003 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:08,101 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:08,114 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:08,115 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,127 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:08,232 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:08,255 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:08,256 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,268 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:08,361 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:08,380 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:08,380 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,393 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:08,495 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:08,520 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:08,521 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,533 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:08,638 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:08,661 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:08,661 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,673 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:08,764 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:08,786 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:08,787 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,798 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664
2014-09-19 10:28:08,892 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - *****************Memory After adding every thing in dictionary****************** 864608
2014-09-19 10:28:08,909 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory After 864524
2014-09-19 10:28:08,910 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Difference 140
2014-09-19 10:28:08,923 [17856] DEBUG OperatingVoltComparison.Program [(null)] <(null)> - Memory Before 864664

After disabling AU's memory consumption almost stable. For disabling AU's, I used following code.

 private static mmAutoUpdaterMode EnableAutoupdaters()
        {
            object objAutoUpdater = null;
            //Create an MMAutoupdater 
            objAutoUpdater = Activator.CreateInstance(Type.GetTypeFromProgID("mmGeodatabase.MMAutoUpdater"));
            autoupdater = objAutoUpdater as IMMAutoUpdater;
            //Save the existing mode
            mmAutoUpdaterMode oldMode = autoupdater.AutoUpdaterMode;//autoupdater.AutoUpdaterMode
            //Turn off autoupdater events
            autoupdater.AutoUpdaterMode = mmAutoUpdaterMode.mmAUMNoEvents;//mmAutoUpdaterMode.mmAUMStandAlone

            return oldMode;
        }

You can call this method before doing any DML operation. I hope this will help to find the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.