"I am creating a class with an Event, then I instantiate the class and dispose of it. VB seems to be wasting 16 bytes each time. " I did some research, and found something really interisting. A small VB.Net application to test this showed that the memory usage slowly increases over time. The object never gets collected. A C# test worked as expected (memory usage increases the 1st time an object is created, and then it stays the same). When I investigated the CLR code for this, I noticed why: C#'s ctor function only created the object, while VB's did the following: IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0007: ldsfld class [mscorlib]System.Collections.ArrayList ConsoleApplication1.LeakingClass::__ENCList IL_000d: newobj instance void [mscorlib]System.WeakReference::.ctor(object) IL_0012: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object) It seems to me as if it is adding the object to an arraylist (only if you have an event declaration in your class). Is this a bug, or was it done for a reason (my best guess would be that it was done in order for other objects to still be able to respond to events raised by this object, even after it was disposed)? And if it was done for a reason, is there a work-around (other than using C#)? I've included my testing code: Imports System.Threading Module Module1 PrivateConst maxGarbageAsInteger = 1000 Sub Main() Dim AfterAsLong Dim BeginAsLong GC.Collect() Begin = GC.GetTotalMemory(True) Console.WriteLine("Memory used at start: {0}", Begin) MakeSomeGarbage() Console.WriteLine("Memory used before collection: {0}", GC.GetTotalMemory(True)) WhileTrue GC.Collect() After = GC.GetTotalMemory(False) Console.WriteLine("Memory used after full collection: {0}", After) Console.WriteLine("Difference: {0}", After - Begin) MakeSomeGarbage() Console.ReadLine() EndWhile EndSub Sub MakeSomeGarbage() Dim vtAs LeakingClass Dim iAsInteger For i = 0To maxGarbage - 1 vt =New LeakingClass() Next i EndSub Sub CreateGarbage() Dim lcAs LeakingClass For iAsInteger = 0To maxGarbage - 1 lc =New LeakingClass() Next i EndSub End Module Public Class LeakingClass Public DelegateSub StatusDel() Public Event StatusAs StatusDel End Class using System; using System.Collections.Generic; using System.Text; namespace ConsoleApplication1 { class Program { private const int maxGarbage = 1000; static void Main() { long Begin; long After; Begin = GC.GetTotalMemory(true); Console.WriteLine("Memory used at start: {0}", Begin); // Put some objects in memory. MakeSomeGarbage(); Console.WriteLine("Memory used before collection: {0}", GC.GetTotalMemory(false)); // Collect all generations of memory. while (true) { GC.Collect(); After = GC.GetTotalMemory(false); Console.WriteLine("Memory used after full collection: {0}", GC.GetTotalMemory(true)); Console.WriteLine("Difference: {0}", After - Begin); MakeSomeGarbage(); Console.ReadLine(); } } static void MakeSomeGarbage() { LeakingClass vt; for (int i = 0; i < maxGarbage; i++) { // Create objects and release them to fill up memory // with unused objects. vt = new LeakingClass(); } } } class LeakingClass { public delegate void StatusDel(); public event StatusDel Status; } |