我正在使用大量的對象(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