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

Поведение GC и захват потоков CLR

Я читал о GC в книге CLR via C#, а именно о том, когда CLR хочет начать сбор. Я понимаю, что он должен приостанавливать потоки перед сборкой, но в ней упоминается, что она должна делать это, когда указатель инструкции потока достигает безопасной точки. В тех случаях, когда он не находится в безопасном месте, он пытается быстро добраться до него, и он делает это через hijacking поток (вставка специального указателя функции в стек потока). Что все прекрасное и денди, но я думал, что управляемые потоки по умолчанию были в безопасности?

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

Итак, что такое safe point в управляемом потоке и как GC может определить, что это такое?

EDIT:

Я не думаю, что я был достаточно конкретным. Согласно этой статье MSDN, даже когда вызывается Thread.Suspend, поток фактически не будет приостановлен до достижения safe point. Далее указывается, что a safe point является точкой в ​​выполнении потоков, при которой может быть выполнена сборка мусора.

Я думаю, что я был неясен в своем вопросе. Я понимаю, что Thread можно приостановить только в безопасном месте, и их нужно приостановить для GC, но я не могу найти четкого ответа на вопрос о том, что такое безопасная точка. Что определяет точку в коде как безопасную?

4b9b3361

Ответ 1

"Безопасные точки" находятся там, где мы находимся:

  • Не в блоке catch.
  • Не внутри наконец
  • Не внутри блокировки
  • Не внутри вызова p/invoke'd (в управляемом коде). Не выполняется неуправляемый код в среде CLR.
  • Дерево памяти доступно.

Точка № 5 немного запутанна, но бывают случаи, когда дерево памяти не будет ходить. Например, после оптимизации CLR может создать новый объект и не назначать его непосредственно переменной. Согласно GC, этот объект будет мертвым объектом, готовым к сбору. Компилятор проинструктирует GC, когда это произойдет, чтобы еще не запустить GC.

Вот сообщение в блоге на msdn с немного дополнительной информацией: http://blogs.msdn.com/b/abhinaba/archive/2009/09/02/netcf-gc-and-thread-blocking.aspx

EDIT: Ну, сэр, я был НЕПРАВИЛЬНО о # 4. См. здесь в разделе "Безопасная точка". Если мы находимся внутри секции кода p/invoke (неуправляемый), тогда разрешено работать до тех пор, пока он снова не вернется в управляемый код.

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