2

I have created a function for exporting to the las in the geometry range by the ILasDataset.Export method.now every time the function when it is called,it takes some memory,but doesn't release that much, meaning on every function call a memory leak happens. **The program has crashed when calling this method about 8,000 times.**Following is the minimal code version of this behaviour:

public static bool ExportLasFromAE(ILasDatasetLayer lasdLayer, IGeometry geometry, string lasSavePath, bool overwrite)
{
    using (ESRI.ArcGIS.ADF.ComReleaser pComReleaser = new ESRI.ArcGIS.ADF.ComReleaser())
    {
        ILasDataset pLasDataset = lasdLayer.Dataset;
        ITrackCancel pCancel = null;
        ILasFilter pLasFilter = new LasFilterClass();
        pComReleaser.ManageLifetime(pLasFilter);
        pLasFilter.AreaOfInterest = geometry;
        ISpatialReference pSpatialReference = lasdLayer.Dataset.SpatialReference;
        string pFileDirectory = System.IO.Path.GetDirectoryName(lasSavePath);
        string pFileName = System.IO.Path.GetFileNameWithoutExtension(lasSavePath);
        string pFileExtensionName = System.IO.Path.GetExtension(lasSavePath);
        //IEnvelope pGeometryEnvelop = geometry.Envelope;
        IRelationalOperator pRelationalOperator = geometry as IRelationalOperator;
        for (int i = 0; i < pLasDataset.FileCount; i++)
        {
            ILasFile pLasFile = pLasDataset.get_File(i);
            IEnvelope pLasFileEnvelope = pLasFile.Extent;
            if (pRelationalOperator.Disjoint(pLasFileEnvelope))
            {
                continue;
            }
            int pFileIndex = i;
            string pFilePath = string.Format("{0}//{1}_{2}{3}", pFileDirectory, pFileName, i.ToString(), pFileExtensionName);

            if (File.Exists(pFilePath))
            {
                if (overwrite)
                {
                    File.Delete(pFilePath);
                }
                else
                {
                    continue;
                }
            }
           pLasDataset.Export(pCancel, pFileIndex, pLasFilter, pFilePath, pSpatialReference, false, false);
        }
    }
    return true;
 }
  • This happens a lot with .net (either VB or C#), it has to do with the (eventual) garbage collector. I have found that you will need to call Collect docs.microsoft.com/en-us/dotnet/api/… frequently and WaitForFullGCComplete(<some timeout in miliseconds>) docs.microsoft.com/en-us/dotnet/api/… sporadically to reduce the memory pressure which avoids the automated process collecting active objects resulting in out of memory errors. – Michael Stimson Oct 26 '18 at 2:25
  • 1
    Your only other viable choice is to code in C++ (Console, NOT CRT) which doesn't use the automated garbage collector relying on the developer to properly dispose of instantiated objects and release allocated memory blocks, which isn't as much fun as it sounds. How often you call the garbage collector and what timeout you use is a matter of experimentation; whatch your code in debug and see where the memory is being gobbled up indicating where to GC.Collect(); and start with a counter of perhaps 1000 and adjust up or down to suit what's happening in your program. – Michael Stimson Oct 26 '18 at 2:29
  • 1
    ArcGIS 10.1 is ancient and bug-ridden. There were hundreds of bugs fixed at 10.2, even before 10.2.1 and 10.2.2 (and the scores of patches since) and it, too, is due for retirement in weeks because of age. At this point, new development using 10.1 is like building a castle on a sand spit. A modern release would bring you closer to bedrock. – Vince Oct 26 '18 at 3:42
  • 1
    That is indeed true @Vince however I have been dealing with this problem since 9.2, it has to do with com objects with a net wrapper, the garbage collector can't properly age the objects and eventually releases an object that is in use under memory pressure, even with GC.KeepAlive stackoverflow.com/questions/38591398/… in context and in use variable objects can be released as the garbage collector considers older objects as more precious even if they aren't referenced again codeproject.com/Articles/1095402/Garbage-Collection-and-Csharp – Michael Stimson Oct 29 '18 at 1:37
1

Instead of the ESRI.ArcGIS.ADF.ComReleaser I prefer to call Marshal.ReleaseComObject from System.Runtime.InteropServices.

At the minimum, I'd try releasing each object created in ExportLasFromAE before returning. You may also need to release pLasFile and pLasFileEnvelope at the end of each loop.

Marshal.ReleaseComObject(pLasDataset);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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