問題描述
我有一個大項目,我的應用程序一直保留我導航離開的頁面.該頁面僅使用最少,并且有很多圖形,因此我希望將其從內存中完全刪除.
I have a big project where my application keeps retaining a page which I navigated away from. The page is only used minimal, and have a lot of graphics, I therefore want it to be completely removed from memory.
因此我使用了以下
NavigationService.RemoveBackEntry();
使用我看到的分析器,上面的代碼片段確保我只有 1 個頁面實例.但由于它的圖形很重,我仍然希望它完全從內存中刪除,即分析器中沒有實例.
Using the profiler I saw that, the above snippet made sure that I would only have 1 instance of the page. But as it is heavy with graphics I still want it to be completely removed from memory, i.e. no instances in the profiler.
在我的大型應用程序中,我嘗試取消訂閱所有事件,引入 dispose/finalize 和調用 GC,它有所幫助,但實例仍然存在.
In my big application I tried to unsubscribe to all events, introduce dispose/finalize and calling GC, it helped some but the instance still existed.
為了排除任何愚蠢的錯誤,我制作了 這個小樣本.僅使用內存彈出檢查器在兩個啞頁面之間導航.但是仍然存在 1-2 個頁面實例.是否有強制刪除頁面以使其沒有任何內容存儲在內存中的方法?
To exclude any stupid errors, I have made this small sample. Only Navigating between two dumb pages with a memory popup checker. But still 1-2 instances of the pages still exists. Is there anyway to force the removal of pages such that nothing of it is stored in memory?
我已添加:
while (App.RootFrame.RemoveBackEntry() != null) ;
到 OnNavigated to,它會刪除除我開始的第一頁之外的所有頁面.我使用了調試分析工具包,可以看到無論我從哪個頁面開始,當我離開它時,它都不會被刪除.
To the OnNavigated to, and it removes all the pages except the first page I start on. I've used the debug analysis toolkit, and can see that no matter what the first page I start on does not get removed, when I navigate away from it.
推薦答案
WP Silverlight 運行時將在內存中最多保留三頁,即使從后臺堆棧中刪除也是如此.我仍然不清楚這種行為的原因,但我找到了一個(丑陋的)解決方法:http://blogs.codes-sources.com/kookiz/archive/2013/11/11/wpdev-give-that-memory-back.aspx
The WP Silverlight runtime will keep up to three pages in memory, even after being removed from the backstack. The reason for this behavior is still unclear to me, but I've found a (ugly) workaround: http://blogs.codes-sources.com/kookiz/archive/2013/11/11/wpdev-give-that-memory-back.aspx
基本上,覆蓋頁面的 OnNavigatedTo
處理程序,并強制垃圾回收 3 次,通過調用調度程序分開:
Basically, override the OnNavigatedTo
handler of your page, and force a garbage collection three times, separated by calls to the dispatcher:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
this.Dispatcher.BeginInvoke(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
this.Dispatcher.BeginInvoke(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
this.Dispatcher.BeginInvoke(() =>
{
GC.Collect();
GC.WaitForPendingFinalizers();
});
});
});
}
聽起來很瘋狂,但它確實有效.
As crazy as it sounds, it works.
在您的情況下,您還有另一個問題.您通過彈出窗口使頁面保持活力.讓我解釋一下:
In your case, you have another problem. You are keeping the page alive with your popup. Let me explain:
在 CreatePopups
方法中,您創建彈出窗口并將其添加到起始頁的網格中.在彈出窗口中,您啟動一??個計時器以定期調用 UpdateMemoryInfo
.計時器由 .NET 運行時保持活動狀態,直到它停止.計時器會在您的彈出窗口中保留一個引用,因為您使用實例方法作為事件處理程序.您的彈出窗口通過 Parent
屬性保持對網格的引用.網格通過其自己的 Parent
屬性保持對頁面的引用.所以你只是讓你的頁面不朽,只要你的計時器在滴答作響.要證明問題存在,只需將 UpdateMemoryInfo
方法設為靜態(并刪除其中的所有 UI 更新代碼).由于事件處理程序現在是靜態的,因此計時器不會保存對彈出實例的引用.運行分析器,您會看到頁面實例現在已按預期被垃圾收集器回收.
In the CreatePopups
method, you create the popup and add it to the grid of the starting page.
In the popup, you start a timer to call UpdateMemoryInfo
at regular interval.
The timer is kept alive by the .NET runtime until it's stopped. The timer keeps a reference on your popup because you're using an instance method as event handler. Your popup is keeping a reference to the grid through the Parent
property. The grid is keeping a reference to the page through its own Parent
property. So you just made your page immortal, for as long as your timer is ticking.
To prove that the issue is there, just make the UpdateMemoryInfo
method static (and remove all the UI updating code there's inside). Since the event handler is now static, the timer won't hold a reference to instance of popup. Run the profiler, and you'll see that the instance of the page is now reclaimed by the garbage collector as you expect.
當然,它假定您的頁面已從后臺堆棧中刪除.通過按返回鍵或調用 NavigationService.GoBack()
方法,或使用 NavigationService.RemoveBackEntry()
手動刪除它們(如果您只使用向前導航)
Of course, it supposes that your pages have been removed from the back stack. Either by pressing the back key or calling the NavigationService.GoBack()
method, or by manually removing them using NavigationService.RemoveBackEntry()
(in case you only use forward navigation)
這篇關于刪除 Pages windows phone的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!