Подходы к управлению памятью
Традиционно языки делятся на две широкие категории:
- Полный контроль через ручное управление памятью: C, C++, Pascal, …
- Программист решает, когда выделять или освобождать память в куче.
- Программист должен определить, всё ещё ли указатель указывает на допустимую память.
- Исследования показывают, что программисты допускают ошибки.
- Полная безопасность через автоматическое управление памятью во время выполнения: Java, Python, Go, Haskell, …
- Система времени выполнения гарантирует, что память не освобождается, пока на неё можно ссылаться.
- Обычно реализуется подсчётом ссылок или сборкой мусора.
Rust предлагает новую комбинацию:
Полный контроль и безопасность благодаря проверке правильного управления памятью во время компиляции.
Это достигается с помощью явной концепции владения.
Этот слайд призван помочь студентам, пришедшим из других языков, поместить Rust в контекст.
-
В C кучей нужно управлять вручную с помощью
mallocиfree. Распространённые ошибки включают забывание вызватьfree, вызов его несколько раз для одного указателя или разыменование указателя после того, как память, на которую он указывает, уже освобождена. -
В C++ есть инструменты вроде умных указателей (
unique_ptr,shared_ptr), которые используют гарантии языка о вызове деструкторов, чтобы память освобождалась при выходе из функции. Всё же этими инструментами легко злоупотребить и получить ошибки, похожие на C. -
Java, Go и Python полагаются на сборщик мусора, который определяет память, до которой больше нельзя добраться, и освобождает её. Это гарантирует, что любой указатель можно разыменовать, что устраняет use-after-free и другие классы ошибок. Но у сборщика мусора есть стоимость во время выполнения, и его трудно правильно настроить.
Модель владения и заимствования Rust во многих случаях может дать производительность C: операции выделения и освобождения выполняются именно там, где они нужны, — с нулевой стоимостью. Она также предоставляет инструменты, похожие на умные указатели C++. При необходимости доступны и другие варианты, например подсчёт ссылок, а есть даже крейты, которые поддерживают сборку мусора во время выполнения (в этом курсе не рассматриваются).