Реализация слабых ссылок
От: es3000  
Дата: 18.05.19 14:21
Оценка:
Здравствуйте!

В ходе обсуждения различных моментов при разработке программы, пришли к выводу, что нужны "слабые" ссылки.
Но в моей среде разработки есть только обычные "жесткие" ссылки.

Помогите, пожалуйста, реализовать самодельный механизм слабых ссылок.

Как я понимаю, должно быть три класса:
1) Класс "Map", который хранит обычную ссылку на объект и его ИД-шник.
2) Класс "WeakRef", которая хранит только ИД объекта.

А как будет удаляться объект из Map, когда он становится больше не нужным?

Получается, нужен специальный метод DeleteFromMap(), который удаляет объект из Map.
То есть нужен базовый класс TWeakBase, у которого реализован этот метод.
И все классы, для которых нужно использование "слабых" ссылок, надо наследовать от этого TWeakBase.

Правильно?

Но тогда получается, что для других классов, не унаследованных от TWeakBase, использование "слабых" ссылок будет невозможно.
Хотелось бы, чтобы и для встроенных классов также можно было использовать слабые ссылки.

Как быть?
Как лучше сделать?

ПС.
Да, я ошибся с разделом.
Моя среда — это не современная .Net. В ней нету слабых ссылок.

Среда очень похожа на старый Visual Basic 6 из старой Visual Studio.
Никакой возможности напрямую управлять указателями и ссылками нету.
Также похоже на старый Delphi (до введения WeakRef).
Отредактировано 20.05.2019 8:30 es3000 . Предыдущая версия . Еще …
Отредактировано 18.05.2019 16:57 es3000 . Предыдущая версия .
Re: Реализация слабых ссылок
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.05.19 14:37
Оценка:
Здравствуйте, es3000, Вы писали:

E>Здравствуйте!


E>В ходе обсуждения различных моментов при разработке программы, пришли к выводу, что нужны "слабые" ссылки.

E>Но в моей среде разработки есть только обычные "жесткие" ссылки.

Причем тут среда разработки? Дотнет у всех практически один и слабые ссылки часть стандартной платформы. Если речь не о дотнете, почему тема в дотнет гуй?
Re: Реализация слабых ссылок
От: bnk СССР http://unmanagedvisio.com/
Дата: 18.05.19 15:04
Оценка:
Здравствуйте, es3000, Вы писали:

E>В ходе обсуждения различных моментов при разработке программы, пришли к выводу, что нужны "слабые" ссылки.

E>Но в моей среде разработки есть только обычные "жесткие" ссылки.

Вообще это вроде как раздел ".NET GUI"?
Какаие нафик слабые и сильные ссылки в .NET? Там же сборщик мусора.

В контексте того, о чем шел разговор в соседнем топике, в .NET "слабая сслыка" будет просто событием (event)
Отредактировано 18.05.2019 15:08 bnk . Предыдущая версия .
Re[2]: Реализация слабых ссылок
От: es3000  
Дата: 18.05.19 16:58
Оценка:
S>Причем тут среда разработки? Дотнет у всех практически один и слабые ссылки часть стандартной платформы. Если речь не о дотнете, почему тема в дотнет гуй?

Да, промахнулся. Написал в пером сообщении.
Как тему перенести?
Re[2]: Реализация слабых ссылок
От: es3000  
Дата: 18.05.19 17:01
Оценка:
bnk>Какаие нафик слабые и сильные ссылки в .NET? Там же сборщик мусора.
bnk>В контексте того, о чем шел разговор в соседнем топике, в .NET "слабая сслыка" будет просто событием (event)

Я отметил в первом сообщении, что я ошибся с разделом.
В моей среде нету слабых ссылок.
Есть сборщик мусора и только обычные сильные ссылки.
Надо как-то реализовать слабые ссылки.
Re[3]: Реализация слабых ссылок
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.05.19 17:05
Оценка:
Здравствуйте, es3000, Вы писали:

E>Да, промахнулся. Написал в пером сообщении.

E>Как тему перенести?

Эту в мусор, в новом месте создать.
Re[3]: Реализация слабых ссылок
От: bnk СССР http://unmanagedvisio.com/
Дата: 18.05.19 17:06
Оценка:
Здравствуйте, es3000, Вы писали:

E>Я отметил в первом сообщении, что я ошибся с разделом.

E>В моей среде нету слабых ссылок.
E>Есть сборщик мусора и только обычные сильные ссылки.
E>Надо как-то реализовать слабые ссылки.

Если есть сборщик мусора, зачем тебе слабые ссылки??? Там обсуждались плюсы.
А сборщик все объекты соберет, даже залинкованные пачками друг на друга.
Re[3]: Реализация слабых ссылок
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.05.19 17:07
Оценка:
Здравствуйте, es3000, Вы писали:

E>Я отметил в первом сообщении, что я ошибся с разделом.

E>В моей среде нету слабых ссылок.
E>Есть сборщик мусора и только обычные сильные ссылки.
E>Надо как-то реализовать слабые ссылки.
Ответ зависит от того, что за среда.
Re[4]: Реализация слабых ссылок
От: es3000  
Дата: 18.05.19 17:46
Оценка:
bnk>Если есть сборщик мусора, зачем тебе слабые ссылки??? Там обсуждались плюсы.
bnk>А сборщик все объекты соберет, даже залинкованные пачками друг на друга.

Сборщик мусора — элементарный: освобождается последняя ссылка — объект удаляется.
А пока есть хоть одна ссылка — объект держится в памяти.
Re[4]: Реализация слабых ссылок
От: es3000  
Дата: 18.05.19 17:47
Оценка:
E>>В моей среде нету слабых ссылок.
E>>Есть сборщик мусора и только обычные сильные ссылки.
E>>Надо как-то реализовать слабые ссылки.

S>Ответ зависит от того, что за среда.


Старая среда — типа старой Delphi. Ну это не суть.
Главное — в ней нету "слабых" ссылок, а они нужны.
Отредактировано 18.05.2019 17:48 es3000 . Предыдущая версия . Еще …
Отредактировано 18.05.2019 17:47 es3000 . Предыдущая версия .
Re[5]: Реализация слабых ссылок
От: bnk СССР http://unmanagedvisio.com/
Дата: 18.05.19 18:02
Оценка:
Здравствуйте, es3000, Вы писали:


bnk>>Если есть сборщик мусора, зачем тебе слабые ссылки??? Там обсуждались плюсы.

bnk>>А сборщик все объекты соберет, даже залинкованные пачками друг на друга.

E>Сборщик мусора — элементарный: освобождается последняя ссылка — объект удаляется.

E>А пока есть хоть одна ссылка — объект держится в памяти.

AFAIK такой алгоритм управления памятью называется не сборка мусора, а "подсчет ссылок".
То есть, сборка мусора в твоей среде отстутствует, но есть подсчет ссылок. У VB6/VBA так например

В контексте MVP лучше говорить не о "слабых ссылках", а о подписке на события, IMHO.
Суть от этого не изменяется.
Re[5]: Реализация слабых ссылок
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.05.19 18:13
Оценка:
Здравствуйте, es3000, Вы писали:

S>>Ответ зависит от того, что за среда.


E>Старая среда — типа старой Delphi. Ну это не суть.

E>Главное — в ней нету "слабых" ссылок, а они нужны.

В общем случае, опираясь лишь на подсчет ссылок, нельзя гарантированно отличить живой объект от мертвого. Любая такая реализация слабых ссылок обречена глючить.
Re[6]: Реализация слабых ссылок
От: es3000  
Дата: 18.05.19 19:13
Оценка:
bnk>То есть, сборка мусора в твоей среде отстутствует, но есть подсчет ссылок. У VB6/VBA так например

Да, точно.

bnk>В контексте MVP лучше говорить не о "слабых ссылках", а о подписке на события, IMHO.

bnk>Суть от этого не изменяется.

Но мне слабые ссылки нужны не только для MVP.
Очень часто возникает такая необходимость.
Re[6]: Реализация слабых ссылок
От: es3000  
Дата: 18.05.19 19:13
Оценка:
S>В общем случае, опираясь лишь на подсчет ссылок, нельзя гарантированно отличить живой объект от мертвого. Любая такая реализация слабых ссылок обречена глючить.

Ну хотя бы с чего-то начать надо.
Re[2]: Реализация слабых ссылок
От: bkat  
Дата: 18.05.19 21:50
Оценка: 4 (1) +1
Здравствуйте, bnk, Вы писали:

bnk>Здравствуйте, es3000, Вы писали:


E>>В ходе обсуждения различных моментов при разработке программы, пришли к выводу, что нужны "слабые" ссылки.

E>>Но в моей среде разработки есть только обычные "жесткие" ссылки.

bnk>Вообще это вроде как раздел ".NET GUI"?

bnk>Какаие нафик слабые и сильные ссылки в .NET? Там же сборщик мусора.

WeakReference. Полезная штука.

bnk>В контексте того, о чем шел разговор в соседнем топике, в .NET "слабая сслыка" будет просто событием (event)


Не уверен, что за контекст там был, но event получается как раз совсем не слабая ссылка, а классический источник memory leak'ов, особенно в GUI.
Re[3]: Реализация слабых ссылок
От: es3000  
Дата: 19.05.19 10:41
Оценка:
B>WeakReference. Полезная штука.

Так вот и я, пока обсуждал другой вопрос, понял что нужны WeakReference.
Но в используемой среде разработки их нету.
Нужно реализовать их "вручную".

B>Не уверен, что за контекст там был, но event получается как раз совсем не слабая ссылка, а классический источник memory leak'ов, особенно в GUI.


Вот как раз одной из причин, почему понадобились WeakReference — это потому что события (и подписчики событий) держат "жесткие" ссылки и не дают объекту освободиться.

Можете подсказать, хотя бы в общих чертах, как разработать самодельный механизм WeakReference?
Отредактировано 19.05.2019 10:42 es3000 . Предыдущая версия .
Re[4]: Реализация слабых ссылок
От: takTak  
Дата: 19.05.19 11:38
Оценка:
E>Можете подсказать, хотя бы в общих чертах, как разработать самодельный механизм WeakReference?

для дельфи такое вот находится :

http://blog.synopse.info/post/2012/06/18/Circular-reference-and-zeroing-weak-pointers

https://blog.dummzeuch.de/2014/06/19/weak-references-or-why-you-should-enable-reportmemoryleaksonshutdown/

https://stackoverflow.com/questions/11501029/weak-reference-down-to-earth-explanation-needed/11501257#11501257

https://stackoverflow.com/search?q=%5Bdelphi%5D+weak+reference
Отредактировано 19.05.2019 11:51 takTak . Предыдущая версия .
Re[4]: Реализация слабых ссылок
От: bkat  
Дата: 19.05.19 18:21
Оценка:
Здравствуйте, es3000, Вы писали:

B>>Не уверен, что за контекст там был, но event получается как раз совсем не слабая ссылка, а классический источник memory leak'ов, особенно в GUI.


E>Вот как раз одной из причин, почему понадобились WeakReference — это потому что события (и подписчики событий) держат "жесткие" ссылки и не дают объекту освободиться.


Ну можно посмотреть как это сделано в .Net
Вот, что нарылось к примеру:
http://www.dotnetframework.org/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/clr/src/BCL/System/WeakReference@cs/1305376/WeakReference@cs

Но врядли это тебе сильно поможет в твоей среде.

Можно подсмотреть как это сделано в мире c++ (std::weak_ptr)
Re: Реализация слабых ссылок
От: qaz77  
Дата: 20.05.19 08:11
Оценка:
Здравствуйте, es3000, Вы писали:
E>Помогите, пожалуйста, реализовать самодельный механизм слабых ссылок.

Чтобы предложить какой-то велосипед, надо знать из чего в твоей среде его можно строить.
Про подсчет ссылок и время жизни объектов все понятно — ОК.

Наверное такой будет минимум вопросов:
1) Какие встроенные/библиотечные контейнеры поддерживаются?
2) Есть ли поддержка шаблонов/дженериков?
3) Можно ли в классы добавлять статические/глобальные поля?
4) Поддерживаются ли вложенные классы?

P.S. Если это что-то Дельфи-подобное, то в Дельфи были сырые указатели Pointer, к которым можно было скастить все что угодно.
Re[2]: Реализация слабых ссылок
От: es3000  
Дата: 20.05.19 08:33
Оценка:
Q>Чтобы предложить какой-то велосипед, надо знать из чего в твоей среде его можно строить.
Q>Про подсчет ссылок и время жизни объектов все понятно — ОК.

Q>Наверное такой будет минимум вопросов:

Q>1) Какие встроенные/библиотечные контейнеры поддерживаются?

Есть аналог коллекций — просто список ссылок.
Есть структура (хранит ключ + значение).
Есть аналог таблицы (список строк с колонками), но хранится в памяти.

Q>2) Есть ли поддержка шаблонов/дженериков?


Нет.

Q>3) Можно ли в классы добавлять статические/глобальные поля?


Нет.

Q>4) Поддерживаются ли вложенные классы?


Нет.

Q>P.S. Если это что-то Дельфи-подобное, то в Дельфи были сырые указатели Pointer, к которым можно было скастить все что угодно.


Среда больше похожа на старый Visual Basic 6 из старой Visual Studio.
Никакой возможности напрямую управлять указателями и ссылками нету.
Только присваивать ссылке созданный объект, и обнулять ссылку с уничтожением объекта, если это последняя ссылка.
Отредактировано 20.05.2019 8:34 es3000 . Предыдущая версия .
Re: Реализация слабых ссылок
От: es3000  
Дата: 20.05.19 09:07
Оценка:
E>В ходе обсуждения различных моментов при разработке программы, пришли к выводу, что нужны "слабые" ссылки.

E>Как быть?

E>Как лучше сделать?

E>Среда очень похожа на старый Visual Basic 6 из старой Visual Studio.


Может быть решением проблемы — метод аналогичный Dispose()?
Re[6]: Реализация слабых ссылок
От: es3000  
Дата: 20.05.19 09:16
Оценка:
bnk>То есть, сборка мусора в твоей среде отстутствует, но есть подсчет ссылок. У VB6/VBA так например

Да, точно. Очень похоже.

bnk>В контексте MVP лучше говорить не о "слабых ссылках", а о подписке на события, IMHO.

bnk>Суть от этого не изменяется.

Ну, при подписке источник событий тоже держит ссылку подписчика.
Подписчик не сможет освободить память пока источник событий не освободил на него ссылки.
Re[3]: Реализация слабых ссылок
От: qaz77  
Дата: 20.05.19 09:25
Оценка:
Здравствуйте, es3000, Вы писали:
Q>>1) Какие встроенные/библиотечные контейнеры поддерживаются?

E>Есть аналог коллекций — просто список ссылок.

E>Есть структура (хранит ключ + значение).
E>Есть аналог таблицы (список строк с колонками), но хранится в памяти.

Q>>2) Есть ли поддержка шаблонов/дженериков?


E>Нет.


Q>>3) Можно ли в классы добавлять статические/глобальные поля?


E>Нет.


Q>>4) Поддерживаются ли вложенные классы?


E>Нет.


Не густо.

Тогда так.
Пусть есть два класса Foo и Bar, для которых мы хотим поддерживать слабые ссылки.

Делаем два вспомогательных класса FooWeakRef и BarWeakRef.
Классы xxxWeakRef имеют конструктор, принимающий id и конструктор без параметров для создания пустой ссылки.
id хранится в единственном поле.
Деструктор ничего не делает!
Для получения доступа к объекту делаем метод Get без параметров, который возвращает сильную ссылку (на Foo или Bar, соответственно).
В своей реализации метод будет обращаться к глобальному контейнеру, откуда вытаскивать ссылку по id (про это ниже).
Если id — пустой (был вызван конструктор без параметров) или по id не найдена ссылка в контейнере (объект удален — на то ссылка у нас и слабая), то метод Get() возвращает пустую ссылку.

Теперь делаем два глобальных контейнера из разряда ключ+значение: FooRefMap и BarRefMap.
Ключом будет id, а значением соответствующая сильная ссылка.
Если в качестве id использовать целочисленные значения (а не GUID, к примеру), то потребуются еще глобальные переменные-счетчики FooRefIdCounter и BarRefIdCounter.
При добавлении элемента в FooRefMap будем инкрементировать значение FooRefIdCounter.

Далее делаем функции помощники для создания и удаления объектов класса Foo (и Bar).
Для создания делаем пачку функции id FooCreate(...), по одной на каждый конструктор Foo.
Для удаления — FooDestroy(id).
Функции FooCreate создают по new новый объект Foo, инкрементируют FooRefIdCounter и заносят пару id+ссылка в FooRefMap, а затем возвращают наружу новый id.
Функция FooDestroy удаляет из FooRefMap элемент по ключу id, при это сам объект разрушается, если на него нет ссылок где-то во временных локальных переменных.

Далее можно автоматизировать вызов функций FooCreate и FooDestroy в классе FooStrongRef — ссылки с семантикой владения.
В нем также запоминаем только id, а в деструкторе вызываем FooDestroy(id).
Метод Get() работает также, как в классе FooWeakRef.
Можно сделать метод FooWeakRef GetWeak(), который будет порождать слабую ссылку FooWeakRef, связанную с нашим id.

В результате в прикладном коде пользуемся только классами FooStrongRef/FooWeakRef (и BarStrongRef/BarWeakRef).
xxxStrongRef — для управления временем жизни, а xxxWeakRef — для слабых связей.
Re[4]: Реализация слабых ссылок
От: es3000  
Дата: 20.05.19 10:21
Оценка:
Q>Не густо.
Q>Тогда так.
...

Спасибо! Попробую реализовать.
Re[4]: Реализация слабых ссылок
От: es3000  
Дата: 21.05.19 13:54
Оценка:
У меня появился новый вопрос про Бизнес-слой.
Создал новую тему:
http://rsdn.org/forum/design/7450258
Автор: es3000
Дата: 21.05.19

Скажите свое мнение в той теме, пожалуйста.
Re: Реализация слабых ссылок
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.05.19 16:20
Оценка:
Здравствуйте, es3000, Вы писали:

E>Как быть?

E>Как лучше сделать?
Изготовить полноценные слабые ссылки в абстрактной хорошо типизированной среде со сборщиком мусора невозможно.
Нужно знать, что это за среда — какие хаки в ней доступны.
К примеру, можно ли перегружать финализаторы; есть ли возможность "подсмотреть" значение ссылки на объект так, чтобы о ней не ведал GC, и т.п.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.