Question: I have a `SerialPort` object. I have put an event handler on this to monitor disposal, exceptions and received data events:

```
mySp.DataReceived += sp_DataReceived;
mySp.ErrorReceived += sp_ErrorReceived;
mySp.Disposed += sp_Disposed;

```

After a few minutes I stop receiving data, but I have good reason to believe this is not an issue with the sender of the serial messages.

I've had issues in this app before with GC disposing things I needed (`Threading.Timer` objects), so I want to make sure this `SerialPort` is not being disposed. I attached a `Disposed` handler, but I've just read GC would not invoke `Dispose` - so how can I tell if it's GC or an issue elsewhere?

Answer: 
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.
To answer the question "how do I know if my objects are collected":

1. Inspect the code. Ensure that you keep a reference to the object in question.
2. You can wrap the object and add a [finalizer](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors) to the wrapper. If you reach the finalizer you know your object is about to be collected.
3. Use a memory profiler. This lets you capture a snapshot and search for the number of objects in memory. That way you can see if whatever object you use exists or not. I'm not aware of any competent free alternative, but there are often trial versions of the commercial systems.

Other things to keep in mind:

1. Ensure you watch for any exceptions and other faults that occur. Some APIs have events or other extension points where you can listen for problems. This might reveal if there is some internal problem causing the messages to stop.
2. Not sure what you are using for serial communication, but some libraries or even drivers can be unreliable. It might be an idea to switch versions or even hardware to see if this avoids the problem.