xBimTeam / XbimEssentials

A .NET library to work with data in the IFC format. This is the core component of the Xbim Toolkit
https://xbimteam.github.io/
Other
485 stars 172 forks source link

ifcstore close does not release the memory consumed during open #471

Open Chandra123539 opened 1 year ago

Chandra123539 commented 1 year ago

Short summary describing the issue. (3-5 sentences)

Assemblies and versions affected:

Xbim.Essentials 5.1.0.0

Steps (or code) to reproduce the issue:

Either ifcstore close or using statement does not free the consumed memory

        public void OpenFile(string sfile)
        {
           using(var store= IfcStore.Open(sfile))
            {

            }
        }

        public MemoryCheck()
        {
            var ifcstore = IfcStore.Open("file");
            ifcstore.Close();
            ifcstore= null;
        }

Minimal file to reproduce the issue:

Any Large file

Expected behavior:

Memory needs to be released

Actual behavior or exception details:

Memory is not freed

Additional Details

Please let us know if we are missing something.

andyward commented 1 year ago

How are you measuring the memory delta? Which profiling tools? What are you seeing? Can you provide a mininal repo including actual versions of xbim being used?

Bare in mind the the underlying framework has some static Metadata it initializes once and caches, there will be a memory increase on first open. But subsequent opens of a model should not increase the footprint (Once GC has kicked in for a couple of generations).

BTW I'd always use Dispose rather than Close. It cleans up more explicitly and calls Close underneath

Chandra123539 commented 1 year ago

Hi Andy,

Thanks for your reply.

Sample Code for Memory Check

        public void MemoryCheck(string sfile)
        {
            Process prc = Process.GetCurrentProcess();

            Console.WriteLine("Before Store Open {0} MB", prc.PrivateMemorySize64 / 1000000);

            var ifcstore = IfcStore.Open(sfile);

            Process prc1 = Process.GetCurrentProcess();

            Console.WriteLine("After Store Open {0} MB", prc1.PrivateMemorySize64 / 1000000);

            ifcstore.Dispose();

            Process prc2 = Process.GetCurrentProcess();

            Console.WriteLine("After Dispose {0} MB", prc2.PrivateMemorySize64 / 1000000);

            ifcstore = null;
        }

I have checked it in VS Studio Diagnostics tools also.

Console Log image

andyward commented 1 year ago

Which version of the libraries are you using? Please supply a full working solution if you can - as a repo.

These figures will not be accurate until Garbage collection has occurred. You should add a couple of GC.Collects after the Dispose() to get a accurate figure. Disposal doesn't free the memory, just makes it ready for collection (which occurs in the background asynchronously). More info

You also need to repeat the Open process again to see if the memory really leaks, or if it's just Lazy Singleton reference data.

How big is the model? Assuming it's fairly large if it's 2.5GB of RAM.

Chandra123539 commented 1 year ago

We are using Latest Xbim.Essentials 5.1.341

After adding couple of GC.Collects along with Dispose image

However, you have suggested to use couple of GC.Collects. Why One GC.Collect would not be sufficient? This is just to understand the concept behind it.

Attached is the Sample repo. IFCStoreTest.zip

IFC file Size is 596MB. Not able to attach IFC file.

andyward commented 1 year ago

It's to do with .NET GC Generations and the Large object heap. Take a look at https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/background-gc & https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/large-object-heap

I will take a look, it may be there's a small leak from a quick test, but nowhere what you're seeing.

Chandra123539 commented 1 year ago

Thanks Andy for your quick reply.