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
Jan Šlegr said:Element class does not release memory when not used 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
Does it make any difference if you explicitly free memory?
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 ' Free memory Set el = Nothing Loop Next End Sub
Regards, Jon Summers LA Solutions
Hi Jon,
no, nothing change (I tried it already).
From outside, without any knowledge what is "inside COM code", it seems like memory is allocated and never released, even when VBA project is unloaded or the design file is closed (in such case, it looks like only the memory holding the file content is released).
Bentley Accredited Developer: iTwin Platform - AssociateLabyrinth Technology | dev.notes() | cad.point
Hi Jan,
this issue is reproducible and is a regression from V8i. Each assignment of an element object let grow the amount of used memory, so a file with just one single element and repeated assignment can be used to reproduce this issue.
We have filed Defect 1104232 with High priority to address this issue.
Best regards,Artur
Answer Verified By: Jan Šlegr
Hi Artur,
thanks a lot for the bug confirmation.
I will create Service Ticket to be assigned to the defect number.
I hope, because it has high priority and possible impact on every VBA or Interop code, it will be fixed in the next (Update 15?) release.
Jan Šlegr said: it will be fixed in the next (Update 15?) release.
it is not yet confirmed, but Update 15 is set as target for this fix.
Best regards,
Artur
I see defect 1104232 in a list of Update 15 fixes. That's great, thanks!
I hope I will find some free time to be able to test it using the code I used in the past, to confirm it's really fixed ;-)
Regards,
from my own tests it looks very good. Please let us know if you still experience any issue.
Thanks