Увеличение UWP-памяти Windows 10 при навигации
У меня есть приложение UWP для Windows 10 и заметил, что использование памяти в диспетчере задач со временем увеличивается.
Я отключил приложение и обнаружил, что память увеличивается при навигации по страницам. Поэтому я сделал простое приложение с несколькими страницами для тестирования, и память все еще растет в этом простом приложении. У меня есть MainPage, который перемещает кадр с страницы 1 на страницу2 и обратно на таймер.
public sealed partial class MainPage : Page
{
private DispatcherTimer _timer;
private bool _page1Showing;
private bool _timerRunning;
public MainPage()
{
this.InitializeComponent();
_timer = new DispatcherTimer();
_timer.Interval = new TimeSpan(0, 0, 0, 0, 200);
_timer.Tick += _timer_Tick;
}
private void _timer_Tick(object sender, object e)
{
GC.Collect();
this.rootFrame.BackStack.Clear();
this.rootFrame.ForwardStack.Clear();
if (_page1Showing)
{
this.rootFrame.Navigate(typeof(Page2));
_page1Showing = false;
}
else
{
this.rootFrame.Navigate(typeof(Page1));
_page1Showing = true;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (_timerRunning)
{
_timer.Stop();
_timerRunning = false;
}
else
{
_timer.Start();
_timerRunning = true;
}
}
}
Page1 и Page2 - это пустые страницы с сеткой с фоновым цветом, чтобы вы могли видеть навигацию. Хотя это приложение запускает использование памяти в диспетчере задач, увеличивается примерно на 1 МБ каждые 30 минут.
Я запустил приложение, используя диагностику памяти в VS2015. Управляемая куча как ожидалось:
![введите описание изображения здесь]()
Куча всегда увеличивается:
![введите описание изображения здесь]()
Сравнение снимков кучи показывает:
![введите описание изображения здесь]()
Я смущен тем, что эти объекты McgInterop? и почему такое простое приложение всегда увеличивается в использовании памяти. Мое основное приложение нужно запускать в течение длительного времени (месяцев +). Цените любую помощь.
Я попытался изменить страницы NavigationCacheMode, если установлено значение Обязательный, страницы создаются один раз. Если установлено значение disabled, страницы создаются каждый раз, и я проверял, что финализатор вызывается как ожидалось.
-
Изменить. Я добавил кнопку, чтобы запустить и остановить таймер (обновленный выше). Кажется, что во время работы таймера использование памяти в диспетчере задач будет увеличиваться, когда таймер остановлен, использование памяти в конечном итоге падает.
Я измерил использование памяти в диспетчере задач в течение дня, начиная и останавливая таймер примерно каждые 2 часа следующим образом: он медленно увеличивается и затем падает в какой-то момент:
<p> 12,5 → 17,1 → 16,7 → 13,9 → 16,8 → 22,5 → 13,6 → 14,6 → 24,9 → 15,2
Итак, я думаю, все работает нормально? Но я не совсем понимаю, что здесь происходит, почему оно растет так сильно? Когда он свободен при каких условиях?
Задерживает ли система освобождение памяти во время навигации по страницам? когда пользователь обычно взаимодействует с экраном?
Ответы
Ответ 1
Можем ли мы увидеть ваш код xaml? Вы используете x: name в своем xaml и уничтожается ли это? Если это может привести к утечке памяти.
Посмотрите на эту ссылку, если вы используете x: name:
http://support.scichart.com/index.php?/News/NewsItem/View/21/wpf-xname-memory-leak--how-to-clear-memory-in-scichart
Конечно, UWP может обрабатывать x: имя по-другому...
Ответ 2
Каждый раз, когда вы переходите на страницу, вы создаете новый экземпляр страницы, но предыдущая страница не размещается (даже если страница уже находится в стеке навигации).
Чтобы предотвратить множественное размещение одной и той же страницы, установите атрибут NavigationCacheMode="Enabled"
на страницу.
Кроме того, чтобы свести к минимуму распределение памяти, вы должны переопределить метод OnNavigatedTo
и OnNavigatedFrom
.
В OnNavigatedTo
метод:
- Создавать экземпляр всех объектов или ресурсов с интенсивной памятью.
- Добавить все обработчики событий, которые вам нужны.
- запускает все таймеры, задачи или потоки.
В OnNavigatedFrom
:
- Утилизировать все ресурсы
- Останавливает все таймеры, задачи или потоки.
- Удалить ссылки со всех тяжелых объектов
- Удалить все обработчики событий
- Только если вам действительно нужно, вызовите GC.Collect()
Ответ 3
Я видел ту же проблему на w8.1 с printInline, используя charmBar, которая потребляет много памяти до краха приложения (1,5 ГБ). но нормально, вам не нужен GC.colect(), он работает автоматически.