|
Программирование >> Формирование пользовательского контейнера
Ключевое отличие сбора мусора от управления памятью вручную заключается в том, что он автоматизирует очистку неиспользуемой памяти. Следовательно, сбор мусора превращает распределение памяти в одношаговую операцию. Например, в языках Java и С# память выделяется для использования с помощью new, но никогда явно не освобождается в программе. Вместо этого периодически запускается сборщик мусора для поиска фрагментов памяти, на которые не указывает ни один объект. Если на какой-либо участок памяти не ссылается ни один объект, - это означает, что данная область памяти в программе не используется, и сборщик мусора, обнаружив такой фрагмент, освобождает его. Таким образом, в системе сбора мусора нет операции delete, да она и не нужна. На первый взгляд, простота, свойственная процессу сбора мусора, может показаться очевидным аргументом в пользу этого способа управления динамической памятью. Действительно возникает вопрос: почему же метод управления памятью вручную до сих пор используется, да еще и в таком мощном языке, как С++? Однако в случае динамического распределения первые впечатления оказываются обманчивыми, потому что оба подхода не лишены ряда недостатков. И только приложением определяется, какой способ подходит более. В следующих разделах приведены некоторые соображения на этот счет. Pro et contra управления памятью вручную Главное достоинство управления динамической памятью вручную - эффективность. Нет сборщика мусора, не тратится время на отслеживание активных объектов или периодический поиск неиспользуемой памяти. Вместо этого программист явно освобождает выделенную память, когда объект, ее занимавший, перестает использоваться, и нет никаких непроизводительных потерь. Поскольку нет расходов на сбор мусора, управление памятью вручную позволяет создавать более эффективный код. Это одна из причин, по которой в языке С++ поддерживается управление памятью вручную: оно позволяет создавать высокопроизводительный код. Другое достоинство такого подхода заключается в возможности контроля. Хотя требуемые от программиста как выделение, так и освобождение памяти, обременительны, взамен он получает контроль над обоими этапами процесса. Вы точно знаете, когда память будет выделена, и когда она освободится. Более того, когда вы с помошью операции delete освобождаете память, отведенную объекту, его деструктор выполняется сейчас же, а не спустя какое-то время, как это может быть в случае сбора мусора. Таким образом, в случае управления памятью вручную вы можете проконтролировать уничтожение размешенного ранее объекта. Несмотря на эффективность, управление распределением динамической памяти вручную чувствительно к весьма досадному типу ошибки: утечке памяти (memory leak). Поскольку память должна освобождаться вручную, можно (легко) забыть сделать это. В результате память остается выделенной, даже если она больше не нужна. Утечки памяти не могут возникнуть в системе со сбором мусора, потому что сборшик мусора гарантированно периодически освобождает память неиспользуемых объектов. Утечки памяти - весьма серьезная проблема программирования в операционной системе Windows, в которой занятая память медленно снижает производительность системы. Другие проблемы, связанные с управлением динамической памятью вручную, включают в себя преждевременную очистку памяти, когда она еще используется, и случайное освобождение одного и того же фрагмента дважды. Обе эти ошибки могут привести к серьезным сбоям. К сожалению, они зачастую не проявляются немедленно, что затрудняет их поиск. Pro et contra сбора мусора Существует несколько способов реализации сбора мусора разной производительности. Но у всех систем сбора мусора есть общие характеристики, которые позволяют сравнить их с параметрами управления динамической памятью вручную. Главные достоинства сбора мусора - простота и надежность. В среде со сбором мусора вы явно выделяете память с помощью операции new, но никогда явно не освобождаете ее. Занятая память очищается автоматически. Следовательно, нет опасности забыть об уничтожении объекта или удалить его раньше времени. Это упрощает программирование и устраняет целый ряд проблем. Более того, нет возможности освободить динамически выделенную память дважды. Таким образом, сбор мусора обеспечивает легкий в использовании, свободный от ошибок, надежный способ управления динамической памятью. К сожалению, за простоту и надежность сбора мусора приходится платить . Первая плата - непроизводительные расходы, связанные с механизмом сбора мусора. Все алгоритмы, реализующие этот механизм, потребляют время процессора, потому что возврат памяти не бесплатный процесс. Таких потерь позволяет избежать лишь способ управления динамической памятью вручную. Второй взнос - потеря контроля над временем уничтожения объекта. В отличие от управления вручную, при котором объект удаляется (вызывается его деструктор) в известный момент времени, - когда для этого объекта выполняется операция delete - у сбора мусора нет такого четкого и быстрого правила. Напротив, когда применяется сбор мусора, объект не уничтожается до тех пор, пока не запустится сборщик и не освободит память, отведенную объекту, а это событие может не произойти до некоторого произвольно выбранного момента времени в будущем. Например, сборшик может не работать до тех пор, пока количество свободной динамической памяти не сократится до определенного количества. Более того, не всегда можно узнать, в каком порядке сборщик мусора уничтожает объекты. Иногда отсутствие сведений о точном времени удаления объекта может вызвать проблемы, так как ваща программа не знает, когда точно будет вызван деструктор для динамически размещенного объекта. В системах сбора мусора, которые выполняются как фоновые задачи, потеря контроля может превратиться в более серьезную проблему для некоторых типов приложений, так как вносит существенную неопределенность в поведение программы. Сборщик мусора, работающий в фоновом режиме, освобождает память в моменты времени, заранее не известные. Например, сборщик мусора обычно выполняется только, когда есть свободное время у процессора. Поскольку подобная ситуация возникает в разное время при выполнении различных программ на разных компьютерах и под управлением различных операционных систем, конкретная точка в запущенной профамме, в которой выполнится сборщик мусора, неопределима. Во многих программах это не создает проблем, но в приложениях реального времени способно породить хаос, поскольку неожиданное выделение сборщику мусора циклов процессора может вызвать пропуск события в таких профаммах. Совместное использование обоих способов Как упоминалось ранее, и управление памятью вручную, и сбор мусора максимизируют одно качество за счет другого. Способ управления вручную обеспечивает максимальные эффективность и контроль в ущерб надежности и простоте использования. Сбор мусора характеризуется максимальной простотой и надежностью, но платит за это снижением производительности и потерей контроля. Таким образом, сбор мусора и управление памятью вручную -. по существу антагонисты, каждый способ максимизирует те качества, которыми другой жертвует. Поэтому ни один подход к управлению динамической памятью не может быть оптимальным для всех возникающих при программировании ситуаций. Несмотря на противоположность, оба варианта управления не исключают Друг друга. Они могут сосуществовать. Следовательно, программист на С++ может иметь доступ к обоим способам, выбирая вручную метод, подходящий для задачи. Все, что нужно для этого, - создать сборщик мусора для С++, чему и посвящена оставшаяся часть данной главы. Разработка сборщика мусора на С++ С++ - мощный и богатый возможностями язык, поэтому встроить в него сборщик мусора можно разными способами. Один очевидный, но ограниченный подход - создание базового класса (base class) сборщика мусора, который в дальнейшем будет наследоваться другими классами при необходимости использования в них сбора мусора. Такой подход позволит вам
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |