tag:blogger.com,1999:blog-8596733192274108952.post6057984181902994559..comments2024-03-12T06:00:18.305+02:00Comments on Programming stuff: Слабые ссылки в .NETSergey Teplyakovhttp://www.blogger.com/profile/14300835272589262297noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-8596733192274108952.post-63612251732617533042013-08-22T17:44:41.208+03:002013-08-22T17:44:41.208+03:00Рад стараться ваше блгрдие! :))Рад стараться ваше блгрдие! :))Sergey Teplyakovhttps://www.blogger.com/profile/14300835272589262297noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-16307449132900296052013-08-22T17:26:20.546+03:002013-08-22T17:26:20.546+03:00Сходимость сошлась :)!!!
Да, так ок. Сходимость сошлась :)!!!<br />Да, так ок. eugenehttps://www.blogger.com/profile/00368111825500921630noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-31887487712459879972013-08-21T19:51:41.515+03:002013-08-21T19:51:41.515+03:00Ок, продолжим:)
Чтобы получить правильный вывод д...Ок, продолжим:)<br /><br />Чтобы получить правильный вывод достаточно в финализаторе поставить Thread.Sleep(100), и в этом случае мы увидим, что слабая ссылка обнуляется еще до завершения финализатора.<br /><br />В текущем же варианте я просто не успеваю задетектить смерть ссылки, поскольку финализатор дергается очень быстро.<br /><br />П.Ы. Может понадобиться для трекания полной смерти тасок, например, или любого другого финализируемого объекта, финализатор которого что-то делает.<br /><br />П.Ы.Ы. В реальности это означает: никогда, или практически никогда:)Sergey Teplyakovhttps://www.blogger.com/profile/14300835272589262297noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-12651666141137378232013-08-21T19:29:13.899+03:002013-08-21T19:29:13.899+03:00Это понятно. Это согласуется с моей картиной мира ...Это понятно. Это согласуется с моей картиной мира :). Я к словам цепляюсь. Когда увидел, что под WeakReference лежит- это многое объяснило. Тогда новый раунд :():<br />Цитирую - <br />Как мы увидели, финализируемый объект умирает дважды. Первый раз, когда на него не остается ссылок из корней приложения, и второй раз – после следующей сборки мусора, уже после вызова финализатора этого объекта.<br /><br />Написано правильно, спору нет. Но вывод на консоль у тебя другой. Получается, что у тебя в примере короткая ссылка умерла после финализатора, а это не так. Т.е по хорошему надо было бы как-то поймать IsAlive до финализатора, но после 1 сборки. В этом случае короткая ссылка должна быть мертвой. <br />П.Ы. А где это может потребоваться? Мне что-то в голову ничего не идет....eugenehttps://www.blogger.com/profile/00368111825500921630noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-18291074524889988132013-08-21T00:46:34.734+03:002013-08-21T00:46:34.734+03:00@eugene: финализатор вызывается не после второй сб...@eugene: финализатор вызывается не после второй сборки мусора, а сразу после первой сборки (асинхронно).<br /><br />Порядок сборки мусора такой:<br />1. Теряются все корни приложения.<br />2. Финализируемый объект перемещается из finalization queue в freachable queue (и воскресает)<br />3. Асинхронно вызывается финализатор в новом потоке<br />4. Ссылка удаляется из freachable queue и объект становится достижим для сборки (умирает второй раз)<br />5. Во время следующей сборки он полностью удаляется.<br /><br />Чтобы убедиться в этом, достаточно вызвать лишь один раз GC.Collect и увидеть, что сразу же после этого вызовется финализатор.<br /><br />Фишка же вся в том, что успешное завершение финализатора является предусловием для недостижимости объекта. До тех пор пока он не отработает, объект является живым (точнее воскресшим).<br /><br />Ведь именно поэтому для полной очистки объектом есть такой паттерн:<br /><br />GC.Collect();<br />// По завршению след. вызова все финализируемые ("воскрешсие") объекты<br />// вновь становятся достижимыми для сборки<br />GC.WaitForPendingFinalizers(); <br />// Добиваем их окончательно<br />GC.Collect();Sergey Teplyakovhttps://www.blogger.com/profile/14300835272589262297noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-45184899455293716352013-08-21T00:15:10.675+03:002013-08-21T00:15:10.675+03:00>>Мы видим, что вначале вызывает >>фин...>>Мы видим, что вначале вызывает >>финализатор нашего объекта и лишь >>потом "обнуляется" короткая >>слабая ссылка. <br /><br />Несколько конфюзит эта фраза. В теории выше ты пишешь, что короткая ссылка умирает, когда объект умирает в первый раз, т.е. когда AppRoots не указывают на объект. Заметь, в этот момент объект ТОЛЬКО перемещается во freachable. Финализатор будет вызван только на след. шаге сборки мусора. Я увидел твой мессадж, что нить финализаторов выполняется очень приоритетно, однако это все равно не объясняет вывода на консоль, где у тебя сначала срабатывает финализатор и лишь потом умирает "короткая" ссылка. Можешь поподробнее здесь?eugenehttps://www.blogger.com/profile/00368111825500921630noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-20402697386990432732013-08-20T15:39:46.324+03:002013-08-20T15:39:46.324+03:00Спс, действительно забыл про Ctrl + F5. Спс, действительно забыл про Ctrl + F5. iBatshttps://www.blogger.com/profile/04494942231239843886noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-61129015559167028382013-08-20T13:04:08.853+03:002013-08-20T13:04:08.853+03:00Игорь, а вы пробовали в релизной сборке и запускал...Игорь, а вы пробовали в релизной сборке и запускали по Ctrl + F5? Тогда должно работать.<br /><br />Да, конечно, объект из очередей удалится автоматом. А если вы его воскресите полность (сохраните ссылку на this во время вызова финализатора), то объект снова можно поместитьв очередь финализации путем вызова GC.ReRegisterForFinalize. Sergey Teplyakovhttps://www.blogger.com/profile/14300835272589262297noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-58383585412309187792013-08-20T11:40:48.564+03:002013-08-20T11:40:48.564+03:00Почему то у меня код не заработал, объекты не хоте...Почему то у меня код не заработал, объекты не хотели умирать) сделал вот так<br /> _wr = new WeakReference(new Finalizable(), trackResurection);<br />и протестировал для каждого кейса отдельно. <br />Но тут также нужно добавить, что помимо того что он окончательно воскреснет, ссылки на него в финализейшин кю больше нет и как показали мои наивные тесты в фричебел кю тоже(так как финализатор больше не вызывался) значит автоматом после того как вызвалась финализация для объекта, он автоматически удалиться из фричебел кю.<br /><br />П.С. достаточно интересный кейс получается, как раз для собеседований )iBatshttps://www.blogger.com/profile/04494942231239843886noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-725780737819532412013-08-20T09:08:27.232+03:002013-08-20T09:08:27.232+03:00@Pavel: поскольку в этом случае объект воскреснет ...@Pavel: поскольку в этом случае объект воскреснет окончательно, то длинная слабая ссылка продолжить указывать на воскресший объект.Sergey Teplyakovhttps://www.blogger.com/profile/14300835272589262297noreply@blogger.comtag:blogger.com,1999:blog-8596733192274108952.post-90104649460298714732013-08-20T05:09:46.357+03:002013-08-20T05:09:46.357+03:00А как поведёт себя long weak reference, есть в фин...А как поведёт себя long weak reference, есть в финализаторе сохранить ссылку на объект куда-нибудь (т.е. вновь создать app root)?Anonymoushttps://www.blogger.com/profile/08972137249743618930noreply@blogger.com