Attached example KML source. Local paths are not supported. Exposing this on a web site should take care of it. You may have to update Icon href in TrafficInformation.kml and link href in Refresh
Add KmlLayer reference to TrafficInformationRefresh.kml
Findings so far:
It appears that there may be several causes for the leak, and I may have identified some. Using ANTS memory profiler, I locate the leak to an impressive number of WeakReferences. Tracing their path, they end up in a few possible hotspots. KmlPlaceMakerSymbol and KmlGraphicsLayer. Looking at the kind of connection, it is PropertyChanged event still having a reference to the map.
When the KML is parsed, new instances of KmlLayer and KmlGraphicsLayer are created. They subscribe to PropertyChanged and Map.PropertyChanged at some point in their construction and initialization. When the layer is refreshed, ChildLayers.Clear() is called from the main layer, but these PropertyChanged events are never unsubscribed. Both parentLayer (which is the KmlLayer I add to the map), and Map lives on throughout the whole lifetime of the application.
I introduced IDisposable to both KmlLayer and KmlGraphicsLayer. Inside of KmlLayer, in every location ChildLayers is called, I instead call a new method named ClearLayers() which will iterate the children and call Dispose before clearing LayerCollection.
KmlLayer.Dispose
- Unsubscribe Map.PropertyChanged
- Iterate and dispose ChildLayers
KmlGraphicsLayer.Dispose
- OnMapChanged(Map, null)
Profiling after making these changes, I still have a memory leak (and memory fragmentation). Now it is KmlPlaceMakerSymbol that is the root of evil. I have not identified what the GC root is now, but it an Object[] related to DataBindings (1 instance).
Since my version of ESRI.ArcGIS.Client is 2.3, I do not know what other changes may have been done to the classes in this assembly that may have fixed this leak in later releases. I am building a stripped down version of Toolkit.DataSources to contain only KmlLayer and related classes.
LayerCollection should have cleaned up Map.PropertyChanged when cleared (or individual items are removed). Or layers themselves should have unsubscribe implemented when they are removed from the map.
This memory leak may also be in effect for other layers as well, but I'm guessing they are not recreated as often as KML services with refresh, so in effect it is probably not something we notice.
In the attached screenshot, there is a KmlGraphicsLayer to the right in the path. Of course, there are more paths that hold these references with a high count.