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

Что такое закрепленные объекты?

Я пытаюсь найти утечку памяти с использованием профилировщика памяти муравьев, и я столкнулся в новом терминах:

Связанные объекты.

Может кто-нибудь дать мне хорошее и простое объяснение того, что это за объекты? Как я могу создать объекты pinn/Unpinn и определить, кто закреплял объекты?

Спасибо

4b9b3361

Ответ 1

Прикрепленный объект - это тот, который не разрешен для перемещения. Сборщик мусора обычно уплотняет память тем, что он перемещает все объекты в "один или несколько кластеров". Это делается для создания больших кусков свободного пространства.

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

Привязка объекта говорит GC, чтобы НЕ ПЕРЕДАТЬ ЭТО. Обычно это бесполезно и ТОЛЬКО имеет смысл при работе с указателями - например, при использовании PInvoke. Иногда вам нужно включить адрес в структуру (в выражении макета памяти), и если это реализовано в классе, вы должны это вывести.

Чтобы ответить на конкретный вопрос:

  • Вы не можете узнать, кто поставил obiect.
  • Закрепление выполняется с помощью оператора FIXED. Это разрешено только в небезопасном коде.

Check:

http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

Ответ 2

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

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

Когда не управляемый объект взаимодействует с вашим кодом (в небезопасных разделах), может возникнуть ситуация, когда где-то есть указатель на часть вашего кода и thinsp; - & thinsp, например, на кусок памяти, адресуемый в вашем код, который обрабатывается внешним COM-вызовом. Эта память не может быть переназначена, так как COM-вызов ожидает, что объект будет находиться в заданном адресе, и, таким образом, если он был перемещен, GC не сможет каким-либо образом уведомить COM-объект об этом изменении, что приведет к доступу нарушение или хуже.

Ответ 3

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

Взаимосвязь с указателями несовместимого кода (например, Win-API) с данными или буферами часто передается как аргумент. Если сборщик мусора мог свободно перемещать эти данные, указатели вдруг стали бы недействительными. Поскольку указатель переносится на неуправляемый код, GC не может обновить указатель - или даже знать, где он используется. Чтобы предотвратить перемещение памяти и убедитесь, что данные остаются в месте, известном неуправляемым указателем кода, объект может быть закреплен.

Ответ 4

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

Когда сборщик мусора запускается, он может удалить объект, который больше не требуется. Это оставляет "дырку" свободного пространства в куче. Затем GC уплотняет кучу, перемещая оставшиеся объекты вместе, чтобы убедиться, что свободное пространство находится в одном непрерывном блоке (что немного напоминает дефрагментацию вашего жесткого диска).

Он также обновляет все ссылки (в управляемом коде) на любые объекты, которые были перемещены как часть уплотнения.

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

Ответ 5

Чтобы привязать объекты, вы можете использовать fixed ключевое слово:

Фиксированный оператор предотвращает сборщик мусора от перемещения подвижная переменная. Фиксированный оператор разрешается только в небезопасных контекст.

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

Решение для нас состояло в том, чтобы использовать класс BitConverter. Если вы посмотрите на базовый код класса BitConverter, вы увидите, что он использует ключевое слово fixed для привязки байтового массива при получении байтов из переменной.

Ответ 6

Прикрепленный объект - это тот, который имеет заданное местоположение в памяти.

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

Вы можете создать их с помощью инструкции fixed: http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx