Почему слабые указатели полезны?

Ответ зависит от VM, который используется:

1) не-SMP : существует один планировщик (поток ОС), который выполняет все процессы Erlang, взятые от пул выполнимых процессов (т.е. те, кто не заблокирован, например, receive)

2) SMP: существуют планировщики K (потоки ОС, K обычно является многими ядрами процессора), который выполняет процессы Erlang от совместно использованная очередь процесса . Это - простая очередь FIFO (с блокировками для предоставления одновременного доступа от нескольких потоков ОС).

3) SMP в R13B и более новый : будет планировщики K (как прежде), который выполняет процессы Erlang от [1 116] несколько очередей процесса . Каждый планировщик имеет свою собственную очередь, так процесс , логика миграции от одного планировщика до другого будет добавлена. Это решение улучшит производительность путем предотвращения чрезмерной привязки совместно использованная очередь процесса.

Для получения дополнительной информации см. этот документ , подготовленный Kenneth Lundin, Ericsson AB, для Конференции пользователей Erlang, Стокгольма, 13 ноября 2008.

15
задан Imagist 28 September 2009 в 03:32
поделиться

7 ответов

Типичным вариантом использования является хранение дополнительных атрибутов объекта. Предположим, у вас есть класс с фиксированным набором членов, и вы хотите добавить больше членов извне. Итак, вы создаете объект словаря -> атрибуты, где ключи являются слабыми ссылками. Тогда словарь не препятствует сборке мусора для ключей; удаление объекта должно также вызвать удаление значений в WeakKeyDictionary (например, посредством обратного вызова).

8
ответ дан 1 December 2019 в 03:04
поделиться

Очень большая проблема - кеширование . Давайте подумаем, как будет работать кеш:

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

В большинстве ситуаций вы не будете использовать собственный механизм кэширования, но обычно используют кеш. Предположим, вы хотите иметь свойство, которое ссылается на объект в кеше, и это свойство остается в области видимости в течение длительного времени. Вы бы предпочли для извлечения объекта из кеша, но если он недоступен, вы можете получить его из постоянного хранилища. Вы также не хотите заставлять этот конкретный объект оставаться в памяти, если давление становится слишком высоким. Таким образом, вы можете использовать слабую ссылку на этот объект, которая позволит вам получить его , если он доступен , но также позволит ему выпасть из кеша.

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

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

9
ответ дан 1 December 2019 в 03:04
поделиться

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

Чтобы исправить это, вы делаете так, чтобы один объект имел сильную ссылку на второй, а второй имел слабую ссылку на первый. Затем, когда исчезает последняя внешняя ссылка на первый объект, первый объект становится кандидатом на сборку мусора, а вскоре после этого - вторым, поскольку теперь его единственная ссылка является слабой.

5
ответ дан 1 December 2019 в 03:04
поделиться

Используйте их, когда вы хотите сохранить кэшированный список объектов, но не предотвращать сбор этих объектов сборщиком мусора, если «настоящий» владелец объекта покончил с этим.

Веб-браузер может иметь объект истории, который хранит ссылки на объекты изображений, которые браузер загружал в другом месте и сохранял в истории / дисковом кэше. В веб-браузере может истечь срок действия одного из этих изображений (пользователь очистил кеш, истекло время ожидания кеша и т. Д.), Но на странице все еще будет ссылка / указатель. Если на странице использовалась слабая ссылка / указатель, объект исчезнет, ​​как ожидалось, и память будет собрана мусором.

1
ответ дан 1 December 2019 в 03:04
поделиться

Другой пример ... не совсем кэширующий, но похожий: предположим, что библиотека ввода-вывода предоставляет объект, который обертывает файловый дескриптор и разрешает доступ к файлу. Когда объект собран, дескриптор файла закрывается. Желательно иметь возможность перечислить все открытые в данный момент файлы. Если вы используете сильные указатели для этого списка, файлы никогда не закрываются.

3
ответ дан 1 December 2019 в 03:04
поделиться

Слабые ссылки могут, например, использоваться в сценариях кэширования - вы можете получить доступ к данным через слабые ссылки, но если вы не обращаетесь к данным в течение длительного времени или существует высокая нагрузка на память, GC может освободить его.

-1
ответ дан 1 December 2019 в 03:04
поделиться

Причина, по которой сборка мусора вообще осуществляется, заключается в том, что в таком языке, как C, где управление памятью полностью находится под явным контролем программиста, Когда право собственности на объект передается, особенно между потоками или, что еще сложнее, между процессами, разделяющими память, избежать утечек памяти и висящих указателей может стать очень сложно. Если это было недостаточно сложно, вам также придется иметь доступ к большему количеству объектов, чем может поместиться в памяти за один раз - вам нужен способ освободить некоторые объекты на некоторое время, чтобы другие объекты может быть в памяти.

Итак, некоторые языки (например, Perl, Lisp, Java) предоставляют механизм, с помощью которого вы можете просто прекратить «использовать» объект, и сборщик мусора в конечном итоге обнаружит это и освободит память, используемую для объекта . Он делает это правильно, и программист не беспокоится обо всех способах, которыми они могут это сделать неправильно (хотя программисты могут это сделать множеством способов).

Если вы концептуально умножите количество раз, когда вы обращаетесь к объекту, на время, которое требуется вычислить значение объекта и, возможно, еще раз умножить на стоимость отсутствия легкодоступного объекта или на размер объекта, так как хранение большого объекта в памяти может предотвратить сохранение нескольких более мелких объектов, вы можете классифицировать разделить объекты на три категории.

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

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

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

Примером этого могут быть изображения. Допустим, у вас есть веб-страница с фотографиями с тысячами изображений для отображения. Вам нужно знать, сколько изображений нужно выложить, и, возможно, вам нужно выполнить запрос к базе данных, чтобы получить список. Память для хранения списка из нескольких тысяч элементов, вероятно, очень мала. Вы хотите сделать запрос один раз и оставить его в покое.

Однако вы можете физически отображать, возможно, только несколько десятков изображений за раз, на панели веб-страницы. Вам не нужно извлекать биты для изображений, на которые пользователь не может смотреть. Когда пользователь прокручивает страницу, вы собираете фактические фрагменты для видимых изображений. Для показа этих изображений может потребоваться много мегабайт. Если пользователь прокручивает назад и вперед между несколькими положениями прокрутки, вам не нужно повторно загружать эти мегабайты снова и снова. Но нельзя постоянно держать все картинки в памяти. Таким образом, вы используете слабые указатели.

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

-1
ответ дан 1 December 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: