[MStn CE U14] VBA and COM/Interop does not release memory

Hi,

based on question for help and analysis that I received from my friend, I think I have to report critical bug in (I think) COM API:

Element class does not release memory when not used, so MicroStation consumes more and more memory until it crashes.

Test case:

Simple 2D design file with a lot of elements, I used an array 1000 x 1000 circles (too big to be shared, but simple to create).

Symptoms:

When active model is iterated (see code below), MicroStation allocates some memory (about 0.5 GB in my test case and VBA code) and this memory is never released (e.g. when macro ends or even when the file is closed). The only way is to close MicroStation and start again.

When Interop assembly is used from C#, the problem is the same, but amount of used memory seems to be higher (I did not do any exact benachmark).

When the same VBA code is run at V8i (SELECTseries 4), no problem with memory exists. In fact, Task Manager does not show any memory increase.

I tested 2 variants of VBA code and 1 version of C# code. VBA V1 is closer to problem inside application we analyzed, because Element IDs are used a lot, so GetElementById is used often.

VBA V1

Public Sub MemoryBenchmark()
    Dim ee As ElementEnumerator
    Set ee = ActiveModelReference.Scan
    Dim i As Integer
    For i = 1 To 10
        Do While ee.MoveNext
            Dim el As Element
            Set el = ActiveModelReference.GetElementByID(ee.Current.ID)
        Loop
    Next
End Sub

VBA V2

Public Sub MemoryBenchmark2()
    Dim ee As ElementEnumerator
    Set ee = ActiveModelReference.Scan
    For i = 1 To 10
        Do While ee.MoveNext
            Dim el As Element
            Set el = ee.Current
        Loop
    Next
End Sub

Based on comparing of VBA V1 and VBA V2 results in Task Manager it seems in VBA 2 the increase is about a half of VBA 1. So I assume the problem is in Element class, because in VBA 2 one extra Element instance is allocated in every iteration.

In C# the code is (namespaces used explicitly):

public void StartBenchmark2()
{
    Bentley.Interop.MicroStationDGN.ModelReference modelIn = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.ActiveModelReference;
    Bentley.Interop.MicroStationDGN.ElementEnumerator elementEnumerator = modelIn.Scan();
    for (int i = 0; i < 10; i++)
    {
        while (elementEnumerator.MoveNext())
        {
            Element interopEle = modelIn.GetElementByID64(elementEnumerator.Current.ID64);
        }
        elementEnumerator.Reset();
    }
}

In C#, I am able to exhaust all available memory easily (Windows 10 running with 32GB RAM).

When the code was rewritten to use DgnPlatformNET, it works fine, no memory increase reported.

Summary:

In a context of analyzed application (but is valid generally) this issue is critical, because it's "migration blocker".

Because of application complexity to rewrite the application to do not use Elements from Interop would probably requires several months plus extra time for extensive testing, so it's not the solution that can be used quickly.

May I ask for testing by somebody else to (not) confirm the problem?

With regards,

  Jan

Parents Reply Children
No Data