Memory usage when is used .NET components


We already had few support request where NAV developers see big memory consumption increase when using .NET component.
Especially when method is inside some loop.
Like in this sample:

  FOR count := 1 TO 10000000 DO BEGIN
        varDOTNET :=varDOTNET.DotNetObject();
        varDOTNET.SetValue('par');
        CLEAR(varDOTNET);
   END;

 

Even it looks like we create variable and then clear it – we can see continues memory usage increase in windows task manager.
But this is not “memory leak” this is how NAV is managing memory. If you start process again then memory usage decrease and increase to the same number.
So only during processing there could be issue that few users running the same code comes to memory limits.
Resolution is to transfer .NET method execution to local function

 FOR count := 1 TO 10000000 DO 
 CallToFunction(‘par’);
…………

PROCEDURE CallToFunction@1(parameter@1170000001 : Text);
VAR
  varDOTNET@1170000000 : DotNet “‘MemoryExample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’.MemoryExample.DotNetObject”;

        varDOTNET :=varDOTNET.DotNetObject();
        varDOTNET.SetValue(parameters);
        CLEAR(varDOTNET);

 

Also here are other coding ways where you can transfer part DotNet variable execution to functions. But it is always more effective transfer execution to function where “garbage collector” can make his job faster and more effective.

 

These postings are provided “AS IS” with no warranties and confer no rights. You assume all risk for your use.

Gedas Busniauskas

Microsoft Lithuania
Microsoft Customer Service and Support (CSS) EMEA


Comments (5)

  1. nutcracker says:

    thank you very much for your posting

    but I can not understand the sentence "If you start process again then memory usage decrease and increase to the same number."

    would you please give me some more explanation?

    thank you again.

  2. Gedas says:

    Nutcracker: If run function and you see that memory consumption increases up to for example 1GB. After function has finished and you started it again – you see that memory consumption dropped to some initial values let say 100MB and increasing again.  

  3. chrclausen says:

    Thanks for sharing. However, I do not agree that this is not a memory leak.

    In your example, when the loop is at round 100, the .NET objects allocated in the preceeding 99 rounds are not used any longer (you cannot access them from your C/AL code,) so these objects are no longer needed. Therefore, keeping these objects in memory is a memory leak, at least according to the top two definitions returned by Bing when searching for "memory leak":

    en.wikipedia.org/…/Memory_leak

    msdn.microsoft.com/…/ms859408.aspx

    Rather than having to train developers to work around the issue, I would prefer if the issue was fixed. Any developer who is a little familiar with .NET garbage collection will be quite surprised that this loop keeps 10 million objects allocated.

  4. Chris says:

    @chrclausen: it is not a memory leak: all references are removed properly, so the garbage collector can do its job. The problem is that the job is done after the method is completed and not while the method is running.

  5. chrclausen says:

    Whatever we choose to call this (for most developers, surprising) behaviour, I would prefer the problem to be fixed in addition to being documented in this post. Most developers would expect CLEAR on a DotNet variable to free the memory allocated, and I struggle to find a good reason for not doing so. If the procedure for some reason runs forever (think of a continuous monitoring process), then the process will at some point run out of memory.