Б. Страуструп - Дизайн и Эволюция C++. 2006 (1160775), страница 58
Текст из файла (страница 58)
В этом случае выражение пем также принимало значение О, а важные приложения оказывались зашигцснными от нехватки памяти. Например: ИИИИИИИ11 Управление памятью Для выполнения второго требования был введен обработчик пем )запс)1ег— определенная пользователем функция, которая гарантированно вызывалась при невозможности выделить память оператором пеи. Например: чо1с) пу Папб1ег)) ( /* ... */ ) чоЫ Г() ( аес пен Папб1ег(агу 'палс)1ег); // начиная с этого момента для. // обработки нехватки памяти // используется му )запб1ег // ) Этот прием описан в )Ягопзсп)р, 19861 и является общим способом обработки ошибок при выделении ресурсов.
С помощью обработчика пем )ганс)1ег можно: о найти дополнительные ресурсы, например свободную память, которую можно выделить; с) вывести сообщение об ошибке и каким-то способом закончить выполнение программы. Применение обработки исключений позволяет программе отреагировать на ошибку не столь радикальным способом, как завершение работы (см. раздел 16.5). 10.7.
Автоматическая сборка мусора 10.7.1. Необязательный сборщик мусора В С++ надо включить необязательный сборшик мусора. Некоторые реализации уже существуют, и переход из исследовательской стадии в промышленную эксплуатацию — лишь вопрос времени. При проектировании С++ я сознательно решил не полагаться на автоматическую сборку мусора, опасаясь весьма значительных издержек по времени и памяти, которые удалось наблюдать в различных сборшиках мусора.
Также могли возникнуть дополнительные сложности при написании компилятора и переносе его на другие платформы. Кроме того, сборка мусора сделала бы С++ непригодным для многих низкоуровневых задач, ради которых язык создавался. По-моему, если вам нужна сборка мусора, то вы можете либо сами реализовать некоторую автоматизированную схему управления памятью, либо воспользоваться языком, который поддерживает сборку мусора напрямую, например старым добрым Яшц!а.
Сегодня и для реализации, и для переноса имеется больше ресурсов. Существует много программ на С++, которые просто нельзя переписать на других языках. Технология сборки мусора усовершенствовалась, а многие из тех доморощенных схем, с которыми я работал, не перешли из отдельных проектов в библиотеки обшего назначения. Но более важно то, что с помощью С++ реализуются все более важные проекты. В некоторых из них сборка мусора определенно была бы полезна, а связанные с ней затра~ы вполне терпимы.
Автоматическая сборка мусора ПИИИИИИИ Главные причины, по которым наличие сборщика мусора желательно, таковы: гз сборка мусора упрощает построение и применение некоторых библиотек; о в некоторых приложениях это средство более надежно, чем написанная пользователем схема управления памятью. Аргументов впротивь несколько больше, но они менее принципиальны, поскольку связаны с реализацией и эффективностью: о сборка мусора сопряжена с такими издержками времени и памяти, которые неприемлемы для многих приложений С++, работающих на существующем оборудовании; гз многие методы сборки мусора вызывают временную приостановку обслуживания, что нетерпимо в таких приложениях, как системы реального времени, драйверы устройств, системы контроля, пользовательский интерфейс на медленно работающем оборудовании и ядра операционных систем; гз ряд приложений не имеет аппаратных ресурсов, типичных для обычного компьютера; о некоторые схемы сборки мусора несовместимы с несколькими базовыми механизмами С, например с арифметическими действиями над указателями, массивами без контроля выхода за границу и неконтролируемыми аргументами функций (типа ргхпсй); о определенные схемы сборки мусора налагают ограничения на способ размещения объекта в памяти или на создание объектов, которые существенно усложняющих интерфейс с другими языками.
Есть и другие аргументы взаь и впротивь наличия сборщика мусора. Сравнивая системы, имеющие и не имеющие сборку мусора, следует помнить; не каждая программа должна работать без остановки; не любой код является частью базовой библиотеки; многие программы могут управлять памятью самостоятельно, без сборки мусора и схожих методов типа подсчета ссылок.
С++ не нужна сборка мусора, так же как и языку без истинных локальных переменных (см. раздел 2.3). Если для управления памятью достаточно более конкретных методов (скажем, специализированных распределителей, см. разделы 10.2, 10А, 15.3.1, 12пд, в5.5.6, 513.10.3)), а также автоматического и статического хранения (см. раздел 2А), то можно получить существенный выигрыш во времени и памяти по сравнению с автоматической сборкой мусора и оператором освобождения памяти.
Общий вывод таков: сборка мусора желательна и возможна, но мы не можем позволить, чтобы от нее была зависима семантика С++ и большинства стандартных базовых библиотек. Значит, реальная проблема заключается в том, стоит ли включать необязательный сборщик мусора для С++. Когда (не «еслиь!) сборщик мусора станет доступен, мы сможем писать программы на С++ двумя способами. В целом это не сложнее, чем управляться с несколькими библиотеками, поддерживать приложение на разных платформах и т.д. Необходимость делать такой выбор — обычное следствие самой природы языка общего назначения, который к тому же широко применяется.
Бессмысленно требовать одинаковой среды выполнения для головки самонаводящейся ракеты, персонального компьютера, телефонного коммутатора, Управление памятью кло~ ~а 13Х1Х, мейнфрейма 1ВМ, компьютера МАС и т д. и т и. Правильно реализованная сборка мусора станет еще одной возможностью при выборе среды выполнения приложения. Может ли данное срелство стать законным и полезньш, если его не специфицировать в станларте С++? Видимо, ла. Но мы не можем включить его в стандарт, поскольку не существует схемы, хоть в какой-то мере прнголной для стандартизации.
Экспериментальные данные должны показать, что схема лостаточно улобна для широкого круга реальных приложений. Кроме того, у нее нс должно быть неустранимых нелостатков, которые слелали бы С++ неприголным лля применения в каком-либо важном классе приложений. При наличии хотя бы олного успешного эксперимента разработчики компиляторов рьяно возьмутся за поиск лучших реализаций. Нам остается только налсяться, что они не выберут несовместимые между собой схемы. 10.7.2. Как должен выглядеть необязательный сборщик мусора? В идеале число программ, которые могут работать как со сборщиком мусора, так и без него, лолжно быть как можно болыпим.
Это важная и трулнолостижимая цель лля разработчиков компиляторов, проектировщиков библиотек и программистов, решающих прикладные задачи. Лучший вариант, если сборка мусора не используется, — компилятор со сбор- шиком мусора должен создавать такую же эффективную по времени и памяти программу, как и компилятор без пан ного средства. Это легко, еслц заставить программиста указать, что «никакая часть этой программы не использует сборку мусора», но очень трулно, если компилятор должен обеспечить максимальную эффективность за счет адаптирующегося алгоритма сборки мусора. Наоборот, разработчику сборщика мусора могут потребоваться «полсказки» со стороны пользователя, чтобы обеспечить приемлемую производительность средства.
Например, может потребоваться указание, лля каких объектов нужна сборка мусора, а для каких — нет (например, когда они созланы в написанной на С или Рогггап библиотеке, не поддерживающей сборку мусора). Если такие полсказки вообще возможны, то компилятор без сборщика мусора должен их игнорировать. Другое решение — прелоставить способ быстро убрать подсказки из исходного текста. Некоторые операции С++, например устаревшие привеления типов, объелинения, состоящие из указателей и не-указателей, арифметические действия над указателями и т.д. плохо сочетаются со сборкой мусора.
В удачно написанной С++-программе такие операции встречаются нечасто, поэтому возникает желание вообще запретить их. Таким образом, вступают в конфликт две возможности: ы запретить небезопасные операции, что делает программу надежней, а сборку мусора более эффективной; ш не запрещать ни олпу С++-программу, правильную с точки зрения текущего определения языка; Думается, что можно найти компромисс и изобрести такую схему сборки мусора, которая подойдет почти для любой корректной С++-программы, а при отсутствии небезопасных операций станет только эффективнее. Автоматическая сборка мусора ~1ИИИИИИ~ При реализации схемы сборки мусора следует решить, нужно ли вызывать деструктор для обьекта, попавшего в мусор.
В ~2пд ~ я писал: «Сборку мусора можно рассматривать как моделирование бесконечной памюи в ограниченном объеме. Имея это в виду, мы можем ответить на вопрос «Должен пи сборщик мусора вызывать деструктор для каждого попавшего в мусор объекта»» Ответ — нет, ток как обьект просто помещен в свободную помять, а не удален и не уничтожен. Если оценивать ситуацию под этим углом, то бетесе — это не более чем требование вызвать деструктор (вместе с извещением системы атом, что память объекта можно использовать повторно~ Но что, если мы действительно хотим выполнить некоторое действие над обьектом, распределенным в свободной памяти, но ток и не удапенныма Донная проблема не касается объектов в статической и автоматической памяти: для них деструкторы всегда вызываются неявно.