我正在使用大量的对象(POI)正在显示在MapControl
上。我正在帮助自己使用MVVM Light来遵守MVVM方法的规则。Windows Phone 8.1 WinRT内存泄漏与ObservableCollection
由于我有义务在地图上显示每个对象,因此我必须使用MapItemsControl
集合,而不是MapElements
。 此集合绑定到相应的ViewModel
中的ObservableCollection<PushpinViewModel>
对象(Pushpins
)。一切都按预期工作,直到这一点,当我想刷新Pushpins
。问题是内存泄漏。但首先,一些代码,以可视化的问题:
XAML:
<maps:MapControl x:Name="Map"
x:Uid="MapControl">
<maps:MapItemsControl ItemsSource="{Binding Pushpins}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Image}"/>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
MainViewModel:
public class MainViewModel : ViewModelBase
{
public RelayCommand AddCommand { get; set; }
public RelayCommand ClearCommand { get; set; }
public RelayCommand CollectCommand { get; set; }
public ObservableCollection<PushpinViewModel> Pushpins { get; set; }
/* Ctor, initialization of Pushpins and stuff like that */
private void Collect()
{
GC.Collect(2);
GC.WaitForPendingFinalizers();
GC.Collect(2);
PrintCurrentMemory();
}
private void Clear()
{
Pushpins.Clear();
PrintCurrentMemory();
}
private void Add()
{
for (int i = 0; i < 1000; i++)
{
Pushpins.Add(new PushpinViewModel());
}
PrintCurrentMemory();
}
private void PrintCurrentMemory()
{
Logger.Log(String.Format("Total Memory: {0}", GC.GetTotalMemory(true)/1024.0));
}
}
PushpinViewModel:
public class PushpinViewModel: ViewModelBase
{
public string Image { get { return "/Assets/SomeImage.png"; } }
~PushpinViewModel()
{
Logger.Log("This finalizer never gets called!");
}
}
现在,请考虑以下情形。我添加到Pushpins
集合1000元素。它们被渲染,内存分配,一切都很好。现在我想清除集合,并添加另一个(在实际场景中不同)1000个元素。所以,我打电话给Clear()
方法。但是..没有任何反应! Pushpins
被清除,但不会调用的终结器!然后我再次添加1000个元素,并且我的内存使用量也增加了一倍。 你可以猜到接下来会发生什么。当我重复这个Clear()
- Add()
程序3-5次我的应用程序崩溃。
那么,这是什么问题?显然ObservableCollection
在对Clear()
执行完毕后,持有对对象的引用,因此它们不能被垃圾收集。当然,强制GC执行垃圾收集并不会有帮助(有时甚至会使情况变得更糟)。
它现在困扰了我2天,我尝试了很多不同的场景来尝试解决这个问题,但说实话,没有任何帮助。 只有一件事值不了 - 我不记得确切的情况,但是当我分配Pushpins = null
,然后做了更多的事情时,VehiceViewModel
被摧毁。但是这对我不起作用,因为我还记得在Clear()
之后,我在地图上显示这些引脚时遇到了问题。
你有什么想法可以导致这种内存泄漏?我如何强制OC
的成员销毁?也许OC
有一些替代方案? 在此先感谢您的帮助!
编辑:
我做了一些测试用XAML地图控件 - https://xamlmapcontrol.codeplex.com/,并且结果是令人惊讶的。总体地图性能增加了> 1000个元素,比本地MapControl
差,但是,如果我打电话Add()
x1000,然后Clear()
,然后Add()
x1000,的终结器被称为!内存被释放,应用程序不会崩溃。所以微软的MapControl
肯定有什么问题...
这个问题可能要加载到形式都被缓存到内存中的位图。收集GC不会将其从缓存中删除。请参阅[这些](http://stackoverflow.com/questions/1684489/how-do-you-make-sure-wpf-releases-large-bitmapsource-from-memory)[相关](http://stackoverflow.com/questions/5530645/released-bitmapimages-used-as-image-control-source-memory-problem)questions。 – 2014-10-04 23:09:43
感谢您的回答。我正在调查这种可能性,并同意这确实可能是一个原因。我检查了你的链接,不幸的是,这里发布的答案主要适用于WPF应用程序(我在WinRT - 通用应用程序中)。我设法从流中加载图片(作为异步方法,但它的工作原理) - 不幸的是它没有帮助。内存消耗更大:( – Malutek 2014-10-05 00:40:02
我不能说你的具体问题,但我也有一些与MapItemsControl有关的问题,我的设置几乎完全相同 - 使用MVVM绑定到ObservableCollection。我导航离开地图到另一个视图,然后回到地图,并且来回地重复3-5次,我会(通常)得到一个“Access Violation”错误,我缩小到MapItemsControl。这种行为需要物品来源,并在地图上为我绘制图钉,请告诉我是否要我发布源代码。 – 2014-10-13 22:49:52