I have a COM object that reads and writes data. I need to read and write using the COM object as fast as possible.
while(!stopLoop)
{
  DateTime t1;
  foreach(Item in Data)
  {
    ReadData(...);
    //...
  }
  DateTime t2;
  TimeSpan loopTime = t2 - t1;
}
I've wrote some code and ran it. At first I have a loopTime of 200ms but it got slower and slower, after 45 minutes it took around 3 seconds. The memory usage doubled in the same time.
I checked with VMMap and: over time only the non-managed heap memory increased. So I guess I have a memory leak in the COM object.
Okay, googled it and tried following:
System.Runtime.InteropServices.Marshal.ReleaseComObject(myObject);
After creating a new object and initialization I could read again:
antiLeakCounter = 0; //as proposed in the comments by Hans Passant
public object ReadData(...)
{
  object obj = new object();
  myComObj.Read(..., ref obj);
  if(++antiLeakCounter == 100)
  {
    //TryRemoveLeak();
    antiLeakCounter = 0;
  }
  return obj;
}
private void TryRemoveLeak()
{
  ReleaseComObject(myComObj);
  myComObj = new MyComClass();
  InitMyComObj();
}
With ReleaseObject I get a continous time again. I am not sure if the COM object works now.
myComObj.Read(..., ref obj); normally returns the ref object that I can check with is bool/byte[]/int, but after ReleaseComObject and recreation the ref object only returns object so I cannot cast it now. So... there must be something wrong with my recreation.
How can I recreate my COM object properly? Or is there a different way to prevent these leaks?
Edit:
I tested with GC.Collect, AddMemoryPressure, etc. but can't get the loop time stable:
private void TryRemoveLeak()
{
  //instead of ReleaseComObject...
}
Test 1:
GC.Collect();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect(GC.GetGeneration(myComObj), GCCollectionMode.Optimized);
Test 4:
public object ReadData(...)
{
  object obj = new object();
  GC.AddMemoryPressure(byteSizeOfObj);
  myComObj.Read(..., ref obj);
  GC.RemoveMemoryPressure(byteSizeOfObj); //after returning, the obj is dead, right?
  return obj;
}
The COM object interacts with another application called PLCSIM.
MyApplication <-COM-> PLCSIM
I checked PLCSIM and can see a memory leak too. It's leaking nearly the same amount like my application in the same time.
 
    