Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923

MVVM Утечка памяти

12.06.2022, 20:22. Показов 4424. Ответов 82
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Собственно сделал подписку: _messageService.MessagesChanged += OnMessagesChanged; в VM.
А отписывать-то как?

Сделал так:

https://github.com/LimeniyeCyb... del.cs#L82

Но даже не понимаю.что сделал. Этого будет достаточно?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.06.2022, 20:22
Ответы с готовыми решениями:

Утечка памяти с картинками
у меня есть вот такой контрол <StackPanel x:Name="StackEmoji" Grid.Row="1" Grid.Column="1" ...

Dispatch timer - Утечка памяти
Всем привет. Пишу на подобные форумы первый раз. Хотел бы попросить помочь разобраться в ситуации с "утечкой памяти". Есть...

Утечка памяти в Awesomium WebControl
Всем привет. Использую в качестве встроенного браузера Awesomium, но вот проблема, уже страниц через 20 процесс awesomium_process.exe...

82
 Аватар для Andrey-MSK
3395 / 2281 / 388
Регистрация: 14.08.2018
Сообщений: 7,731
Записей в блоге: 4
16.06.2022, 21:59
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
C#
1
BindingOperations.EnableCollectionSynchronization (ICollection.SyncRoot);
Да, читал про это, но манёк не то... Везде советуют именно модифицированную ObservableCollection... Осталось разобраться в этой куче предложений
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
16.06.2022, 22:07
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Везде советуют именно модифицированную ObservableCollection...
Обычно "модифицируют" через маршалинг всех операций в UI поток.
Это подойдёт только для редко обновляемой коллекции единичными элементами.
Для быстрых обновлений и/или пакетных обновлений нужна локировка.
2
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
16.06.2022, 22:22  [ТС]
Элд Хасп, я просто ни разу не видел синглтон VM и мне это упёрто не даёт покоя: "да как это так-то, в VM и синглтон?!".

Вроде как VM, это просто коннектор, что-то простое, без лишних сложных реализаций по типу этого же синглтона, разве нет?
Пока синглтон -- очень удобный вариант для решения проблемы с утечкой памяти, но я сомневаюсь в его надёжности. Мне кажется, что такими действиями я навязываю ему функциональность уровня модели.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
16.06.2022, 23:22
Цитата Сообщение от limeniye Посмотреть сообщение
я просто ни разу не видел синглтон VM и мне это упёрто не даёт покоя: "да как это так-то, в VM и синглтон?!".
Зависит от задачи.
Очень часто это возможно и значительно упрощает реализацию приложения.
Те же локаторы и сервисы по сути создают тот же самый синглтон, но не на уровне ViewModel, а на уровне View.

Синглтон несколько нарушает принципы ООП и Solid, так как VM не может знать сколько её экземпляров понадобятся View.
Но в реальных приложениях вам часто приходилось сталкиваться с динамическим пересозданием VM и/или создание нескольких её экземпляров?
Такое бывает нужно очень редко.

При достаточном опыте, надобность в синглтонах отпадает, так как довольно хорошо представляешь себе как всё друг с другом связанно и ошибок работы с разными экземплярами просто не допускаешь.
Поэтому на более высоком уровне (знаний), синглтоны редко используются.

Добавлено через 4 минуты
Цитата Сообщение от limeniye Посмотреть сообщение
Вроде как VM, это просто коннектор, что-то простое, без лишних сложных реализаций по типу этого же синглтона, разве нет?
В идеале VM - это прокси отражающее Модель через свои свойства.
Но если у вас одна Модель (а это 99% приложений), то можно и Модель и VM сделать синглтонами.
Что сложного вы увидели в реализации синглтона - я не понимаю.
Для этого нужно только закрыть её единственный конструктор и предоставить единственный экземпляр через статическое свойство.

Добавлено через 3 минуты
Цитата Сообщение от limeniye Посмотреть сообщение
я сомневаюсь в его надёжности
Надёжности в чём?
Как бы безопасность он несколько ухудшает, так как к статическому экземпляру есть доступ отовсюду.
Но если вы хотите строить действительно безопасное (с точки зрения хака) приложение, то Шарп в целом для этого не шибко подходит.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
16.06.2022, 23:30  [ТС]
Элд Хасп, ну получается так, что я создаю Model в singlton, а потом ещё и Vm в singlton. Всё singlton'ю, а по сути синглтон вообще
Цитата Сообщение от Элд Хасп Посмотреть сообщение
несколько нарушает принципы ООП и Solid
Мне кажется singlton'a в Model достаточно, просто в VM нужно сделать отписку от события в определённый момент, например реализовав IDisponsable интерфейс, на всякий случай.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
17.06.2022, 00:03
Цитата Сообщение от limeniye Посмотреть сообщение
просто в VM нужно сделать отписку от события в определённый момент
Определённый момент - это перед тем как вы затираете последнюю ссылку на экземпляр VM.
По вашим словам такого момента в вашем приложении нет.
Если так, то значит вы где-то, сами не зная того, создаёте новые ненужные экземпляры VM.
И надо выявить где это происходит и пресечь это.

Цитата Сообщение от limeniye Посмотреть сообщение
например реализовав IDisponsable интерфейс, на всякий случай.
Вы реализовали "а кабы был!".
Он у вас ничего не делает, нигде не вызывается, и только захламляет код.
Dispose() - должен вызываться для освобождения НЕУПРАВЛЯЕМЫХ ресурсов.
И где у вас такие?

Цитата Сообщение от limeniye Посмотреть сообщение
Собственно сделал подписку: _messageService.MessagesChanged += OnMessagesChanged; в VM.
А отписывать-то как?
Если у вас экземпляр VM не должен существовать до конца сеанса приложения, то нужно:
Цитата Сообщение от Элд Хасп Посмотреть сообщение
_messageService.MessagesChanged надо сделать слабым событием, чтобы подписка на него не удерживала экземпляр
Но по вашим словам у вас экземпляр VM существует всё время сеанса, вы его никогда не уничтожаете, следовательно и сложности эти не к чему.
Надо искать где вы создаёте ненужные экземпляры VM, если дело, вообще, в этом.
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
17.06.2022, 14:41  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если так, то значит вы где-то, сами не зная того, создаёте новые ненужные экземпляры VM.
И надо выявить где это происходит и пресечь это.
Мне просто сказали: "в Вас есть утечка памяти".

По-моему это было тут
https://github.com/LimeniyeCyb... ewModel.cs

(а может и не тут, я не помню). В общем, почему утечка -- не знаю, я маслёнок в этом (

Нужно почитать и посмотреть на эту тему тем.
0
 Аватар для Andrey-MSK
3395 / 2281 / 388
Регистрация: 14.08.2018
Сообщений: 7,731
Записей в блоге: 4
18.06.2022, 13:09
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Самый простой способ это работа в VM с ObservableCollection через ICollection.SyncRoot.
Получается вот это работает в VM, что-то типа такого
C#
1
2
3
4
5
6
7
8
ICollection myCollection = someCollection;
lock(myCollection.SyncRoot)
{
    foreach (object item in myCollection)
    {
        // Insert your code here.
    }
}
А вот где делать вызов BindingOperations.EnableCollectionSynchronization (ICollection.SyncRoot);? Ведь эта штука из

Namespace:
System.Windows.Data
Assembly:
PresentationFramework.dll


BindingOperations.EnableCollectionSynchronization Method

Можно какой нить простой примерчик для MVVM?
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
18.06.2022, 14:13  [ТС]
Andrey-MSK, как я понял вот так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public ObservableCollection<Students> Students { get; } = new ObservableCollection<Student>();
 
public MainViewModel()
{
    BindingOperations.EnableCollectionSynchronization (((ICollection)Students).SyncRoot);
    _someModel.Added += OnStudentAdded;
}
 
private void OnStudentAdded(object sender, Student student)
{
    lock(((ICollection)Students).SyncRoot)
    {
        Students.Add(student);
    };
}
Добавлено через 2 минуты
Но если да, тогда я не понимаю зачем нужна тогда строка 5.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
18.06.2022, 14:49
Цитата Сообщение от Andrey-MSK Посмотреть сообщение
А вот где делать вызов BindingOperations.EnableCollectionSynchr onization (ICollection.SyncRoot);? Ведь эта штука из:
По простому - в конструкторе VM при условии что она создаётся в UI потоке (99.9% реальных задач).
По феншую - при создании экземпляра VM на уровне App, там же происходит и вызов этого метода или передавать в VM делегат метода вызова.

Так же надо помнить что если возможна замена коллекции или VM нужно уничтожить, то нужно отписывать привязки от коллекции (DisableCollectionSynchronization).

Цитата Сообщение от Andrey-MSK Посмотреть сообщение
Получается вот это работает в VM, что-то типа такого
В самом простом варианте да.
Для очень динамичного изменения, можно реализовать локировку только во время записи.

Добавлено через 8 минут
Цитата Сообщение от limeniye Посмотреть сообщение
как я понял вот так
Тоже верно.
Вероятность очень маленькая, то всё же есть когда по времени совпадут обновления UI и добавление единичного элемента.
Но это (как и пример от Andrey-MSK) скорее относится к потокобезопасности чем к исключениям от обновления из других потоков.
Для предотвращения исключений в представлении достаточно просто уведомить о локере и потом можно "забыть" про это.

А вот для группового обновления (AddRange) это весьма полезно, так как до завершения всех обновлений коллекции обновление её представления не будет происходить.

Цитата Сообщение от limeniye Посмотреть сообщение
Но если да, тогда я не понимаю зачем нужна тогда строка 5.
В WPF без неё, если вызвать метод OnStudentAdded не из UI потока - будет исключенее.
В UWP - не будет.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
18.06.2022, 14:53  [ТС]
Элд Хасп, то есть по сути эта строка свойству SyncRoot коллекции задаёт текущий Dispatcher ?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
18.06.2022, 15:05
Цитата Сообщение от limeniye Посмотреть сообщение
то есть по сути эта строка свойству SyncRoot коллекции задаёт текущий Dispatcher ?
В какой-то мере.
Это нюансы реализации ItemsControl.
Если есть локер, то происходит маршалинг CollectionChanged в UI поток.
Если нет локера, то просто выкидывается исключение.
Сделано так из-за того, что ItemsControl не знает какой механизм потокобезопасности будет использован при работе с коллекцией.
Для более сложных способов (чем простой локер) используется перегрузка EnableCollectionSynchronization(IEnumerable, Object, CollectionSynchronizationCallback).
Поэтому в простых случаях, достаточно уведомить о локере, чтобы просто предотвратить выброс исключений.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
18.06.2022, 15:55
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Сделано так из-за того, что ItemsControl не знает какой механизм потокобезопасности будет использован при работе с коллекцией.
Не совсем верно - уточню.
ItemsControl контрол - это DependecyObject. Дефолтным для DependecyObject является обеспечение поткобезопасности через работу работу со всеми данными в одном и том же потоке связанном с Диспетчером этого DependecyObject.
Если же изменение данных происходит в других потоках, то для ItemsControl - это неизвестный механизм и происходит выкидывание исключения.

Вообще, конечно, с маршалингом событий в MS перемудрили.
В WPF PropertyChanged автоматически маршализируется в UI поток, а CollectionChanged и CanExecuteChanged - нет.
В UWP - наоборот: CollectionChanged и CanExecuteChanged - маршализируются , а PropertyChanged - нет.
Зачем эту путаницу ввели - ума не приложу.
Сделали бы для всех маршалинг или без него.
Из-за этого приходится учитывать особенности типа View на уровне VM и даже, иногда, Model.
Если бы не это, то почти всегда можно было бы реализовывать VM в Standard.
И уже потом выбирать какого типа подключать к ней View.
1
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
18.06.2022, 16:47  [ТС]
Элд Хасп, Вы постоянно говорите "маршалинг".
Но для меня это очень расплывчатая тема. Искал по этому поводу информацию: это вообще для среиализации и дессериализации данных. Есть ещё класс Marshal, как мне помнится, он вроде что-то там с неуправляемыми ресурсами делает
Что такое класс Marshal

Вообще путаюсь зачем вообще нужен "маршалинг"
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
18.06.2022, 17:05
Цитата Сообщение от limeniye Посмотреть сообщение
Вы постоянно говорите "маршалинг".
Я не знаю откуда взялся этот термин, но вот пример его использования //Cant do this from a background thread and has to marshal.
Marshal - очень многозначное слово. Возможно в программировании используется смысл "размещать".

Надо поинтересоваться о происхождении термина у тех кто более подкован в теории и основах Шарпа.
OwenGlendower и kolorotur можете что-то прояснить?

Добавлено через 3 минуты
limeniye, что интересно - Гугл переводчик не переводит его на русский смысл, а транслитерирует.
То есть по его мнению, это уже устойчивый термин и для русского программ. сленга.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
18.06.2022, 17:08
limeniye, вот и русское толкование: Маршалинг
Применение
Маршалинг применяется при передаче данных между процессами и/или потоками, например:

- при использовании различных механизмов RPC;
- при использовании P/Invoke на платформе .NET Framework (при переходе от неуправляемого типа в тип CLR);
Добавлено через 2 минуты
Маршалинг события - это получение данных из метода вызванного в одного потоке и вызов метода с этими данными в другом потоке.
0
 Аватар для limeniye
1182 / 624 / 160
Регистрация: 19.04.2018
Сообщений: 2,923
18.06.2022, 17:30  [ТС]
Я понимаю как сереализовать .xml или .json формат в какой-то CLR тип, например.
Не знаю как это работает под капотом, но думаю это не особо важно.

Я более-менее пониманию как работает RPC сериализация: перевод в байты и десериализация байт в CLR.

А вот:
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Обычно "модифицируют" через маршалинг всех операций в UI поток.
совсем не понимаю. Для чего тут нужна эта преславуя "сериализация" (она же "маршалинг", как я понял -- это одно и то же) ?
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
18.06.2022, 18:09
Цитата Сообщение от Элд Хасп Посмотреть сообщение
можете что-то прояснить?
Оно в шарп и другие языки из английского пришло: маршал — ответственный за движение/направление кого/чего-либо.
Работник аэродрома, машущий самолетам фонариками или принимающий/запускающий с авианосцев — маршал.
to marshal (маршаллить) — производный глагол. ЖД вагоны на сортировочной станции маршаллятся.
Не проверял, но не удивлюсь если звание Маршал в вооруженных силах оттуда же (или наоборот) — тот, кто движет войсками.

Marshal в программировании — часть системы, ответственная за направление/перевод данных из одной среды в другую: в шарпе — из неуправляемой в управляемую и наоборот.
2
18.06.2022, 18:27

Не по теме:

Цитата Сообщение от Andrey-MSK Посмотреть сообщение
И да, в VM using System.Windows;, из-за Application.Dispatcher, нужно найти реализацию потоконезависимой ObservableCollection...
https://github.com/reactivemarbles/DynamicData

0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2892
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
18.06.2022, 19:53
Цитата Сообщение от limeniye Посмотреть сообщение
совсем не понимаю. Для чего тут нужна эта преславуя "сериализация" (она же "маршалинг", как я понял -- это одно и то же) ?
Сериализация вовсе не причём.
Относительно ObservableCollection - это перекидка события CollectionChanged (обычно метода подымающего событие) в UI поток.

Простейший пример такого "модифицированного" ObservableCollection:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    public class DispatcherObservableCollection<T> : ObservableCollection<T>
    {
        private static readonly Dispatcher staticDispatcher = Application.Current.Dispatcher;
 
        public DispatcherObservableCollection()
        {
        }
 
        public DispatcherObservableCollection(IEnumerable<T> collection) : base(collection)
        {
        }
 
        public DispatcherObservableCollection(List<T> list) : base(list)
        {
        }
 
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            // Проверка потока.
            if (staticDispatcher.CheckAccess())
                base.OnCollectionChanged(e);
            else
                // Маршалинг вызова метода в поток диспетчера.
                staticDispatcher.BeginInvoke(OnCollectionChanged, e);
        }
    }
Добавлено через 10 минут
Проблема такой реализации в зависимости Dispatcher от типа View и как следствие несовместимость реализаций Framework, Core (.Net), UWP.
По идее такой класс должен писаться на Standard, а в нём нет Dispatcher.
Приходится определять контекст синхронизации потоков слушателей и маршилировать в них.
Такая реализация уже значительно сложнее.
Пример для команд: Исполнение делегатов обобщённого типа
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.06.2022, 19:53

Возможна ли утечка памяти в следующем коде
Имеем следующу последовательность высокочастотных операций, требуется оптимизация т к память съедает в течении дня до 1 Гб: ...

Утечка памяти при обновлении текста TextBlock
При каждом тике таймера обновляется текст TextBlock'a. private void Paint(object sender, EventArgs e) { ...

Утечка памяти при большом количестве сообщений
Есть окно сообщения.При новом сообщения создается новое окно(анимировано),старое закрывается(Close).В этом окне есть одно Image.Если много...

Программа не может продолжить работу, так как недостаточно памяти. Утечка в WPF?
В общем, есть у меня контрол, который наследует от Image, воспроизводит анимацию просто сменяя изображения из массива. А сменяются...

HttpWebRequest, расход памяти непомерно больших объемов и , как следствие, утечка памяти
Добрый вечер. Мне была поставлена такая задача. Написать приложение, которая загружает из списка ссылки с сайта и ищет там определенную...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru