I have a few objects in my application which are identified as being alive, when I don't believe they should be.

According to the "Type instance details" tab, they are only reachable by root, which gives no Instance/Field/Method that encapsulates the reference. The objects have gone through their dispose methods, and have disconnected from all events that .NET Memory Profiler was previously able to identify. At this juncture I am at a loss. Does anyone have any ideas as to what else I could check to see what is keeping these objects alive?

The object type in question only derives from interfaces. I don't see any warnings or messages in the profiler, for this type. I do not see any additional information when showing unidentified roots or instances not in root paths.

If a root is only presented as <root> then the .NET runtime has reported a root, but the profiler has not been able to identify it. If you are running under .NET Framework prior to v4.0, this can for instance happen for thread static fields. It can also happen for instance that are used in COM interop and other interop scenarios. What does the full root path look like? Is there anything that indicates what type of root is is (e.g. if it is a thread static field, you should be able to see ThreadStaticBuckets in the root path)?

The full root path has just <root>. It's only the one level in the path.

To my knowledge, there are no Thread static variables in our application code. Are there any known controls or components which would keep references in such a storage specifier? Is there any build property we might have on which would hide some references from the profiler?

If you have direct <roots> to your instances, then it cannot be a static fields (or thread static field) as they will not be presented as direct roots. Method roots are direct roots, but they should be identified by the profiler. However, due to a bug in the profiler, method roots were not correctly identified when profiling a .NET Framework 4.0. Unfortunately, this doesn't affect your application since you run under .NET 2.0, but it might still be a good idea to update to the latest version of the profiler (v3.5.159).

As mentioned previously, the runtime creates internal roots in some interop scenarios, and in a few other cases as well. However, it's pretty uncommon and I don't see it very often.

BTW, how do you start profiling your application? If you attach to the process, it's harder for the profiler to identify roots, and you might see many more unidentified <roots>.