With the GC we can never say if it is or when it is collected - only if it CAN be collected. The rule is "the GC can collect everything that does not have a chain of strong references to a application root." If you got that, the GC will not touch it. If you do not have it the GC may touch it - eventually.
Running the GC is expensive. While it collects, all other threads must pause. Accordingly the Framework is lazy at running it. If it only runs once - on application closure - that is the ideal case. Before that only some rare scenarios can get it into action:
- The danger of a OOM Exception. Before those happen, the GC will have collected everything it can.
- Manually calling it
- various optimsiations. Like trying to collect everything you created inside the function you just finished.
- any alternate GC strategy, like the one optimized for servers
As for your problem:
As long as you keep a strong reference to something, it can not be collected.
If you got a strong reference, the GC has to assume you are working on it and it is not supposed to remove it. It may still do other background stuff with it (like moving it around in memory), but those changes are usually invisible for you.
The only way to cause a memory leak with a GC like this, is to forgetting to remove all strong references to something. Mostly it is people forgetting to remove it from a Collection.
Event handlers by design do not count as "a unbroken chain of strong references". GUI Automatics already have a strong reference chain to everything that is displayed (and the stuff that is only hidden, not undisplayed).
I think you are doing some wierd way of multitasking like this:
- you create a instance
- you register events
- you do not keep a strong reference
This will not work. You need to use a proper way of multitasking - ideally using some blocking or polling code - to process them. That would also allow you to get Exceptions out of the SerialPorts.