0

We're developing a large scale Unity3D-based video game and we've become concerned that a major memory leak is occurring due to some bad event subscriber disposal somewhere. Unfortunately we haven't been able to attach any of the popular C# profilers to determine the root cause of the memory leak.

We thought one quick way to determine if there is a loose end in our event system is to write a quick method we could run during runtime to export all the Action properties in all of our objects with a count of the current subscribers.

The hope here is that we quickly see some huge numbers in a couple of events and can quickly identify the missing -= unsubscribe.

The question I have here is: Is there a way to iterate over all our objects to collect all event handlers and count their subscribers?

I've made a quick start on iterating over our units. However I'd love a type-generic way to do it as we have a lot of derived types in our game.

public static object ExportAllEvents(params string[] args)
{
    foreach (var wUnit in GameData.LEVEL.getUnits())
    {
        foreach (var eventInfo in wUnit.GetType().GetEvents())
        {
            // Hrmmm...
        }
    }

    // TODO: CSV export here

    return "Success";
}
S.Richmond
  • 11,412
  • 6
  • 39
  • 57
  • I suggest you change to a mediator pattern – Ewan Apr 07 '15 at 11:34
  • We're way too late into the project to make design changes. We just need to clean up at this point. – S.Richmond Apr 07 '15 at 11:34
  • I thought that might be your reason for not doing so. I guess my doubt is that writing 'super reflection export app' will be quicker than refactoring – Ewan Apr 07 '15 at 11:37
  • I am not absolutely certain, but I am fairly sure that this kind of thing would require working with the (unmanaged) .NET debugging & profiling APIs; likely the same APIs that debuggers and profiling tools (such as Red Gate's ANTS) use. The next best thing in managed land are likely to be performance counters, but they're probably too coarse-grained in your case. – stakx - no longer contributing Apr 07 '15 at 11:39
  • Another option (that I don't have enough knowledge of to go into detail, sorry) would be to use a AOP library (e.g. PostSharp) that hooks into all your types' events. If you could use AOP to explicitly implement all events' `add` and `remove` accessors, you could inject some kind of (un-) subscription logging, then run your program, then evaluate the produced log for missing unsubscriptions. – stakx - no longer contributing Apr 07 '15 at 11:42
  • I would like to avoid any kind of heavy library injection for a number of reasons, least of which is that we're in a semi-closed environment in Unity3D - Which is a .NET ~3 Mono equivalent. – S.Richmond Apr 07 '15 at 12:13

1 Answers1

0

Well it was already answered here: How to get a delegate object from an EventInfo? Basically, given an EventInfo, you need to get its FieldInfo And the GetValue of the FieldInfo is a Delegate =)

Community
  • 1
  • 1
Nanorock
  • 26
  • 1
  • 3