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

Почему `` Box:: new` не возвращает `Option` или` Result`?

Я не понимаю, почему Box::new не возвращает Option или Result.

Распределение может завершиться неудачно, потому что память не является неограниченной, или что-то еще может произойти; Каково поведение в таких случаях? Я не могу найти никакой информации об этом.

4b9b3361

Ответ 1

Более общий вид Что делать в Out Of Memory (OOM)?

В работе с OOM существует множество трудностей:

  • обнаружение,
  • восстановление из него (изящно),
  • интегрируя его в язык (изящно).

Первый вопрос - это его обнаружение. Многие ОС сегодня, по умолчанию, используют пространство подкачки. В этом случае ваш процесс на самом деле находится в затруднительном положении, прежде чем вы попадете в ситуацию OOM, потому что использование пространства подкачки значительно замедлит процесс. Другие ОС будут убивать низкоприоритетные процессы, когда более высокий процесс требует большего объема памяти (убийца OOM) или обещает больше памяти, чем в настоящее время, в надежде, что он не будет использоваться или будет доступен к моменту, когда это необходимо (overcommit), и т.д...

Вторая проблема - восстановление. На уровне процесса единственным способом восстановления является освобождение памяти... без выделения какого-либо времени. Это не так просто, как кажется, например, нет гарантии, что паника и размотка не потребуют выделения памяти (например, акт хранения сообщения о панике может выделяться, если это делается небрежно). Вот почему текущая rustc runtime отменяет по умолчанию на OOM.

Третья проблема - языковая интеграция: распределение памяти происходит повсюду. Любое использование Box, Vec, String и т.д. Итак, если вы избегаете панического маршрута и используете маршрут Result вместо этого, вам нужно настроить почти любую сигнатуру метода мутации для учетной записи такого рода отказа, и это будет пузыриться во всех интерфейсах.

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

Это важно, потому что это означает, что очень мало ситуаций, когда (1) разрешено динамическое распределение памяти и (2) его отказ должен обрабатываться изящно самим процессом.

И на данный момент можно только задаться вопросом, сколько средств бюджета должно быть потрачено на это, и насколько сложна эта проблема для 99% программ, которые не заботятся.

Ответ 2

Я обнаружил следующее сообщение между разработчиками Rust относительно некоторых функций нижнего уровня в liballoc, не возвращающих Option s: PR # 14230.

В частности, следующие части объясняют некоторые причины этого:

huonw

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

alexcrichton

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

huonw

Я думал с точки зрения отказа задачи, которая не может быть восстановлена ​​на сайте вызова, то есть библиотека более высокого уровня может выйти из строя, но абсолютные минимальные строительные блоки не должны, так что люди могут справляться с проблемами по своему усмотрению ( даже если он просто запускает запуск задачи вручную). Если liballoc не предназначен для библиотеки распределения нижнего уровня, неудача в порядке. (Кстати, я думаю, вы, возможно, неправильно истолковали мой комментарий, потому что я не говорил о libcore, просто liballoc.)

alexcrichton

Ой, извините! Я полагаю, что интерфейс основного распределителя (расположенный в liballoc) будет запрограммирован, чтобы не сработает!(), Только примитивы поверх них (например, оператор коробки).

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

Ответ 3

Это решение для языкового дизайна. Вы должны учитывать не только логику одной операции (например, Box::new), но и то, как это повлияет на эргономику языка. Если бы мы справлялись с ошибками выделения памяти с помощью механики Return, тогда эти ошибки начали бы всплывать повсюду. Даже если этот метод не выделяет память в куче в настоящее время, он может прибегнуть к нему в будущем. Внезапно произойдет простое изменение в реализации, потому что вам придется изменить API, который с семантическим управлением версиями означает крупный выпуск. Все это для небольшой пользы, поскольку обработка из памяти не очень надежна или полезна в присутствии подкачки и убийц памяти (часто вы должны прекратить выделение памяти задолго до того, как вы получите ошибку из памяти).

Тема обсуждалась на reddit.

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