Подтвердить что ты не робот

Являются ли слабые ссылки С# на самом деле мягкими?

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

Насколько я знаю, нет четкого утверждения о том, как слабые ссылки влияют на время жизни объекта в .NET. Если они являются истинными слабыми refs, они не должны влиять на него вообще, но это также делает их довольно бесполезными для их, я считаю, главной цели кеширования (я там не прав?). С другой стороны, если они действуют как soft refs, их имя мало вводит в заблуждение.

Лично я полагаю, что они ведут себя как мягкие ссылки, но это просто впечатление и не основано.

Реализация детали применима, конечно. Я спрашиваю о менталитете, связанном с слабыми ссылками .NET, - могут ли они расширять время жизни или ведут себя как истинные слабые ссылки?

(Несмотря на ряд связанных вопросов, я еще не нашел ответа на эту конкретную проблему.)

4b9b3361

Ответ 1

Я не видел никакой информации, которая указывает, что они увеличили бы время жизни объекта, на который они указывают. И статьи, которые я прочитал об алгоритме, который использует GC для определения достижимости, также не упоминают об этом. Поэтому я ожидаю, что они не будут влиять на время жизни объекта.

Слабое
Этот тип дескриптора используется для отслеживания объекта, но позволяет его собирать. Когда объект собирается, содержимое GCHandle обнуляется. Слабые ссылки обнуляются перед запуском финализатора, поэтому даже если финализатор воскрешает объект, ссылка" Слабая "все еще обнуляется.

WeakTrackResurrection
Этот тип дескриптора похож на Weak, но дескриптор не обнуляется, если объект был воскрешен во время финализации.

http://msdn.microsoft.com/en-us/library/83y4ak54.aspx


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

  • Генерация объекта больше, чем генерация GC. Это особенно интересно для больших объектов, которые выделяются на кучу больших объектов и всегда считаются Gen2 для этой цели.
  • Объекты с финализатором и всеми доступными для них объектами выживают из GC.
  • Может существовать механизм, когда прежние ссылки со старых объектов могут содержать молодые объекты в живых, но я не уверен в этом.

Ответ 2

Являются ли слабые ссылки С# мягкими?

Нет.

Я там не прав?

Вы ошибаетесь. Цель слабых ссылок абсолютно не кэшируется в том смысле, о котором вы говорите. Это распространенное заблуждение.

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

Нет, они не расширяют время жизни.

Рассмотрим следующую программу (код F #):

do
  let x = System.WeakReference(Array.create 0 0)
  for i=1 to 10000000 do
    ignore(Array.create 0 0)
  if x.IsAlive then "alive" else "dead"
  |> printfn "Weak reference is %s"

Эта куча выделяет пустой массив, который сразу же подходит для сбора мусора. Затем мы зацикливаем 10M раз, выделяя больше недостижимых массивов. Обратите внимание, что это вовсе не увеличивает давление памяти, поэтому нет никакой мотивации для сбора массива, на который ссылается слабая ссылка. Тем не менее программа печатает "Слабая ссылка мертва", потому что она была собрана, тем не менее. Это поведение слабой ссылки. Мягкая ссылка была бы сохранена до тех пор, пока ее память не понадобилась.

Вот еще одна тестовая программа (код F #):

open System

let isAlive (x: WeakReference) = x.IsAlive

do
  let mutable xs = []
  while true do
    xs <- WeakReference(Array.create 0 0)::List.filter isAlive xs
    printfn "%d" xs.Length

Это позволяет отфильтровать мертвые слабые ссылки и добавить новый на передний план связанного списка, каждый раз распечатывая длину списка. На моей машине это никогда не превышает 1000 выживших слабых ссылок. Он растет, а затем падает до нуля в циклах, по-видимому, потому, что все слабые ссылки собираются в каждой коллекции gen0. Опять же, это поведение слабой ссылки, а не мягкая ссылка.

Обратите внимание, что это поведение (агрессивная коллекция объектов с низкой ссылочной позицией в коллекциях gen0) именно то, что делает слабые ссылки плохим выбором для кешей. Если вы попытаетесь использовать слабые ссылки в своем кеше, вы обнаружите, что ваш кеш сильно покраснел без причины.

Ответ 3

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