There was an interesting bug in NMock until recently (it's been fixed) which saw memory usage during unit test runs increase in relation to the total number of mock objects created during the run. The culprit was .Net's inability to unload assemblies from a running AppDomain: each mock was being hosted in a brand new dynamic assembly - which never gets garbage collected - so you could easily end up with a few hundred assemblies languishing in the root domain, eating memory. We fixed it by creating one assembly for all mock types, and by caching identical types for the duration of the test run.
Today, another bug was raised against NMock, which involved calling GetManifestResourceNames() on all loaded assemblies. Dynamic assembliles will throw NotSupportedException for this method (and for a couple of others), so if any code which relies on this call is used alongside NMock (in this case it was NVelocity), we break it.
I looked at a couple of workarounds, including saving our mock assembly to disk and reloading it as a static assembly so it could play nicely, but noticed that AssemblyBuilder, which we use to generate the mock assembly, is never garbage collected either! So, kids, be aware that if you generate assemblies at runtime, even just to save them to disk, your AssemblyBuilders will hang around for ever, holding you memory hostage and calling you "poo-breath" behind your back. The solution, of course, is to do your code-gen in a separate AppDomain, which is pretty weak but at least you can throw it away when you're done.
Does anyone have a good reason why assemblies cannot be garbage collected?