5

Does anybody know if there is a way of preventing a memory leak in RuntimeBinder when using "dynamic" keyword with __ComObject instances in C#?

I got the following code:

var t = Type.GetTypeFromCLSID(new Guid("BB06C0E4-D293-4f75-8A90-CB05B6477EEE"));
while (true)
{
    dynamic o = System.Activator.CreateInstance(t);
    Marshal.ReleaseComObject(o);
}

This leaks LocalVariableSymbol class instances (and other from the Microsoft.CSharp.RuntimeBinder.Semantics namespace).

Replacing "dynamic" with "object" i.e.:

    object o = System.Activator.CreateInstance(t);

fixes the leak but I'd prefer to keep using dynamic (the actual code is much more complex and makes use of "dynamic").

I know the RuntimeBinder singleton caches the data and this causes the leak but do you know if there's any way to cleanup the cache etc.?

Many thanks!


Similar questions:

Related links:

Marcin Zawiejski
  • 1,123
  • 1
  • 9
  • 23
  • 1
    I've also raised a ticket for this on Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/1925659 – Marcin Zawiejski Oct 21 '15 at 14:02
  • Did you found another solution ? I'm unable to use the object type – J4N Nov 30 '15 at 07:12
  • Unfortunately I got no news on this yet – Marcin Zawiejski Nov 30 '15 at 07:48
  • I think I've found a way of using the "dynamic" keyword in the case with no memory leaks: "object o = Systen,Activator.CreateInstance(t); dynamic d = o;" and then use d as usual. Have checked this with a memory profiler and it no longer reports the leaks. – Marcin Zawiejski Nov 30 '15 at 10:14
  • I will try, but in my case, I don't have any call to CreateInstance, I only have public static field of type Dynamic. So not sure where to put this additional step – J4N Nov 30 '15 at 10:17
  • I think you can try to lookup for the dynamic static field assignments in your code and then replace any direct assignments like "MyClass.TheStaticDynamicField = ..." with a "object o = ...; MyClass.TheStaticDynamicField = o;". I've checked this with a static field (instead of a local variable) and it no longer leaks for me with the workaround however I got no idea why this fixes the problem. – Marcin Zawiejski Nov 30 '15 at 10:29
  • I'm currently trying to remove most of the dynamic. I replaced all the static registration as "dynamic"(since it's more when I used them that I need to have their exact implementation). I'm almost done. I think after that I will have to make that my methods receive an object/some-more-generic-interface and then typecast it as dynamic to see if that solve the issue. – J4N Nov 30 '15 at 12:09
  • I tried your proposal, for me it doesn't change anything for now. I also tried to do stuff only in non-anonymous method(I think that the callSite maybe different otherwise) – J4N Nov 30 '15 at 15:35

2 Answers2

5

The solution in my case was to replace:

dynamic o = System.Activator.CreateInstance(t);

with:

object o = System.Activator.CreateInstance(t);
dynamic d = o;

The memory leak no longer occurs having the workaround applied.

Marcin Zawiejski
  • 1,123
  • 1
  • 9
  • 23
  • **That actually works!** In one case I'm aware of, changing method signature from `void Foo(dynamic x) { ... }` to `void Foo(object x) { dynamic y = x; ... }` did the trick. – ForNeVeR Jan 31 '17 at 07:40
-2

I had a similar problem: Using "dynamic" caused a memory leak.

I solved this in the following way:

using (dynamic attr = curve.Attributes)
{
  if (attr != null)
    return attr.InternalLabel;
}
Robert
  • 108
  • 1
  • 11