Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does using a delegate create garbage

I'm working on a game for the xbox360, using XNA. On the Xbox the garbage collector performs rather badly compared to the one on a PC, so keeping garbage generated to a minimum is vital for a smoothly performing game.

I remember reading once that calling a delegate creates garbage, but now for the life of me can't find any references to delegates creating garbage. Did I just make this up or are delegates messy?

If delegates are messy, bonus points for suggesting a workaround.

public delegate T GetValue<T>(T value, T[] args);

public static T Transaction<T>(GetValue<T> calculate, ref T value, params T[] args) where T : class
{
    T newValue = calculate(value, args);
    return foo(newValue);
}

My code looks vaguely like that at the moment, the only solution I can think of to rid myself of delegates is to pass in a class which inherits an interface IValueCalculator, and then I can call the method on that interface, that's not really very neat though!

like image 545
Martin Avatar asked Oct 17 '09 17:10

Martin


People also ask

What triggers garbage collection in C#?

The garbage collector automatically detects when an object is no longer needed and removes it, freeing up the memory space allocated to that object without affecting objects that are still being used.

What is a delegate How is it type safe?

A delegate is a type-safe function pointer that can reference a method that has the same signature as that of the delegate. You can take advantage of delegates in C# to implement events and call-back methods. A multicast delegate is one that can point to one or more methods that have identical signatures.

Are delegates immutable?

After a delegate is created, the method it is associated with never changes; delegate objects are immutable.

Can users prevent garbage collection?

Garbage collection is performed automatically. We cannot force or prevent it. Objects are retained in memory while they are reachable. Being referenced is not the same as being reachable (from a root): a pack of interlinked objects can become unreachable as a whole, as we've seen in the example above.


1 Answers

In the desktop environment garbage is effectively free. There what you want to worry about is how much non-garbage you are producing. Remember how the garbage collector works: it first marks all known objects, then it clears the mark on all live objects and compacts the live objects. The expensive step there is "unmark the live objects". Destroying the garbage is cheap; it's identifying the live objects that is expensive, and that cost depends on the number of live objects you have (and the complexity of their reference topology), not on the number of dead objects you have.

However, on XBOX and other compact frameworks, the garbage collector runs quite frequently and runs more often when new allocations are created, so yes, you are correct to worry about creating garbage too. You want to both keep the live set small (so as to make a collection cheap) and not make new allocations (because that triggers collections.)

Creating a delegate does allocate memory, but calling one is nothing more than calling a method named Invoke on a class. A delegate is not much more than a class with a method named Invoke that happens to immediately call another method when it is called.

Regardless, if you have a problem with memory performance then the right thing to do is to get out the memory profiler and use it to analyze your program. Casting about at random wondering if this or that happens to allocate memory is like trying to weed your garden with nail scissors; it takes a lot of time and doesn't actually accomplish your goals. Use a profiler to analyze your performance and see where the problems are, and then fix them.

like image 169
Eric Lippert Avatar answered Sep 22 '22 00:09

Eric Lippert