Windows Phone 7 용 Silverlight에서 하나의 응용 프로그램을 개발 중입니다. Windows 전화 응용 프로그램에서는 제공되지만 어떤 방식 으로든 벗어날 수없는 매우 일반적인 문제에 빠져 있습니다. 첫 페이지에서 두 번째로, 네 번째에서 네 번째로 네비게이션하는 동안 여러 번 메모리 누출 문제가 발생합니다.WP7 탐색 - 목록 상자 바인딩의 WP7 메모리 누수 문제
해결하려면 두 개의 빈 페이지가있는 새 프로젝트를 하나 만듭니다. 각 페이지에는 현재 메모리 및 피크 메모리를 인쇄하는 2 개의 텍스트 블록과 다음 또는 이전 페이지로 이동하는 하나의 버튼이 있습니다. 페이지 1에서 페이지 2로 이동할 때, 나는 3 가지를 모두 null 참조로 만들고 gc.collect를 호출하여 페이지 참조를 파기합니다. 같은 방식으로 2 페이지에서 1 페이지로 이동하면서도 동일한 작업을 수행합니다.
또한 500 밀리 초마다 타이머에서 gc.collect()를 호출하려고했지만 여전히 결과가 없습니다. gc.collect()를 완전히 제거하면 메모리가 MB 단위로 증가하므로 반드시 필요한 것입니다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using System.Windows.Threading;
namespace AppMemory
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
txtCM.Text = "C : " + Microsoft.Phone.Info.DeviceStatus.ApplicationCurrentMemoryUsage.ToString();
txtPM.Text = "P: " + Microsoft.Phone.Info.DeviceStatus.ApplicationPeakMemoryUsage.ToString();
}
// Simple button Click event handler to take us to the second page
private void Button_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
while (this.NavigationService.BackStack.Any())
{
this.NavigationService.RemoveBackEntry();
}
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
while (this.NavigationService.BackStack.Any())
{
this.NavigationService.RemoveBackEntry();
}
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
dosposeMemory();
base.OnNavigatedFrom(e);
this.DataContext = null;
GC.Collect();
}
public void dosposeMemory()
{
try
{
if (txtCM != null)
{
txtCM.Text = null;
txtCM = null;
}
if (txtPM != null)
{
txtPM.Text = null;
txtPM = null;
}
if (btn1 != null)
{
btn1.Click -= Button_Click;
btn1.Style = null;
btn1.Resources.Clear();
btn1.Resources = null;
btn1 = null;
}
if (ContentPanel != null)
{
ContentPanel.Children.Clear();
ContentPanel.Resources.Clear();
ContentPanel.Resources = null;
ContentPanel = null;
}
if (LayoutRoot != null)
{
LayoutRoot.DataContext = null;
LayoutRoot.Background = null;
LayoutRoot.Resources.Clear();
LayoutRoot.Resources = null;
LayoutRoot.Children.Clear();
LayoutRoot = null;
}
if (app1 != null)
{
app1.Resources.Clear();
app1.Resources = null;
app1 = null;
}
GC.Collect();
}
catch(Exception)
{
}
}
~MainPage()
{
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(new System.Action(() =>
{
GC.Collect();
}));
}
}
}
두 번째 페이지 :
메인 페이지 : 여기
내 코드의 조각입니다
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace AppMemory
{
public partial class Page1 : PhoneApplicationPage
{
public Page1()
{
InitializeComponent();
textBlock1.Text = "C : " + Microsoft.Phone.Info.DeviceStatus.ApplicationCurrentMemoryUsage.ToString();
textBlock2.Text = "P: " + Microsoft.Phone.Info.DeviceStatus.ApplicationPeakMemoryUsage.ToString();
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
while (this.NavigationService.BackStack.Any())
{
this.NavigationService.RemoveBackEntry();
}
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
while (this.NavigationService.BackStack.Any())
{
this.NavigationService.RemoveBackEntry();
}
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
dosposeMemory();
base.OnNavigatedFrom(e);
this.DataContext = null;
GC.Collect();
}
public void dosposeMemory()
{
try
{
if (textBlock1 != null)
{
textBlock1.Text = null;
textBlock1 = null;
}
if (textBlock2 != null)
{
textBlock2.Text = null;
textBlock2 = null;
}
if (ContentPanel != null)
{
ContentPanel.Children.Clear();
ContentPanel.Resources.Clear();
ContentPanel.Resources = null;
ContentPanel = null;
}
if (LayoutRoot != null)
{
LayoutRoot.Children.Clear();
LayoutRoot.Resources.Clear();
LayoutRoot.Resources = null;
LayoutRoot = null;
}
if (page1 != null)
{
page1.Resources.Clear();
page1.Resources = null;
page1 = null;
}
GC.Collect();
}
catch (Exception)
{
GC.Collect();
}
}
}
}
다음
각각 증가 현재 메모리의 추적을 시도 :
Try Page 1 Page 2
1 7426048 7442432
2 6959104 8257536
3 6934528 8454144
4 8622080 8458240
5 8626176 8470528
6 8630272 8470528
질문 : 1) 내 흐름과 방법이 메모리 관리와 앞뒤로 네비게이션에 적합한가요? 2) 내 메소드가 텍스트 블록에 대한 참조를 null로 만들고 버튼이 적절합니까? 3) 또한 내 실제 프로젝트에서 나는 listbox에서 데이터 바인딩을 사용하고 있는데, 나는 다음과 같은 방식으로 destrcuted했다.
if (listCountry != null)
{
listCountry.SelectionChanged -= listCountry_SelectionChanged;
//listCountry.Items.Clear();
listCountry.DataContext = null;
listCountry.ItemsSource = null;
listCountry.Resources.Clear();
listCountry.Resources = null;
listCountry = null;
}
내 프로젝트에는이 목록 상자가 여러 번 사용되기 때문에 의심 스럽습니다.
나는 연구와 업데이트에서 많은 시간을 보냈지 만 현재와 최고 메모리에 대한 해결책을 얻지 못했기 때문에 나를 빼 버려주세요.
미리 감사드립니다. David Jacobs.
샘플에 링크를 추가하십시오. 아무도 자신의 PC를 다시 작성할 수 없으므로 –
Alex입니다. 이것은 내 PC의 데모 프로젝트입니다. 두 페이지의 코드를 모두 넣었습니다. –
이 누출은 WP7의 탐색 서비스의 정상적인 동작 일 수 있습니다. 이것을 확인하려면 p1 -> p2 -> p1에서 탐색하여 시나리오를 재현 한 다음 p2로 돌아온 다음 p1 –