Сборка мусора

Поделись знанием:
Перейти к: навигация, поиск

В программировании сборка мусора (устоявшийся термин,[1] с точки зрения русского языка правильнее «сбор мусора»,[2] англ. garbage collection, GC) — одна из форм автоматического управления памятью. Специальный процесс, называемый сборщиком мусора (англ. garbage collector), периодически освобождает память, удаляя объекты, которые уже не будут востребованы приложениями.

Если бы память компьютера была бесконечной, можно было бы просто оставлять ненужные объекты в памяти. Сбор мусора — эмуляция такого бесконечного компьютера на конечной памяти.[3] Многие ограничения сборщиков мусора (нет гарантии, что финализатор выполнится; управляет только памятью, но не другими ресурсами) вытекают из этой метафоры.





История

Сборка мусора была впервые применена Джоном Маккарти в 1959 году в среде программирования на разработанном им функциональном языке программирования Лисп. Впоследствии она применялась в других системах программирования и языках, преимущественно — в функциональных и логических. Необходимость сборки мусора в языках этих типов обусловлена тем, что структура таких языков делает крайне неудобным отслеживание времени жизни объектов в памяти и ручное управление ею. Широко используемые в этих языках списки и основанные на них сложные структуры данных во время работы программ постоянно создаются, надстраиваются, расширяются, копируются, и правильно определить момент удаления того или иного объекта затруднительно.

В промышленных процедурных и объектных языках сборка мусора долго не использовалась. Предпочтение отдавалось ручному управлению памятью, как более эффективному и предсказуемому. Но со второй половины 1980-х годов технология сборки мусора стала использоваться и в директивных (императивных), и в объектных языках программирования, а со второй половины 1990-х годов всё большее число создаваемых языков и сред, ориентированных на прикладное программирование, включают механизм сборки мусора либо как единственный, либо как один из доступных механизмов управления динамической памятью. В настоящее время она используется в Oberon, Java, Python, Ruby, Perl, C#, D, F# и других языках.

Проблемы ручного управления памятью

Традиционным для директивных языков способом управления памятью является ручной. Его сущность в следующем:

  • Для создания объекта в динамической памяти программист явно вызывает команду выделения памяти. Эта команда возвращает указатель на выделенную область памяти, который сохраняется и используется для доступа к ней.
  • До тех пор, пока созданный объект нужен для работы программы, программа обращается к нему через ранее сохранённый указатель.
  • Когда надобность в объекте проходит, программист явно вызывает команду освобождения памяти, передавая ей указатель на удаляемый объект.

В любом языке, допускающем создание объектов в динамической памяти, потенциально возможны две проблемы: висячие ссылки и утечки памяти.

Висячая ссылка (англ. dangling pointer)
Висячая ссылка — это оставшаяся в использовании ссылка на объект, который уже удалён. После удаления объекта все сохранившиеся в программе ссылки на него становятся «висячими». Память, занимаемая ранее объектом, может быть передана операционной системе и стать недоступной, или быть использована для размещения нового объекта в той же программе. В первом случае попытка обратиться по «повисшей» ссылке приведёт к срабатыванию механизма защиты памяти и аварийной остановке программы, а во втором — к непредсказуемым последствиям.
Появление висячих ссылок обычно становится следствием неправильной оценки времени жизни объекта: программист вызывает команду удаления объекта до того, как его использование прекратится.
Утечка памяти (англ. memory leak)
Создав объект в динамической памяти, программист может не удалить его после завершения использования. Если ссылающейся на объект переменной будет присвоено новое значение и на объект нет других ссылок, он становится программно недоступным, но продолжает занимать память, поскольку команда его удаления не вызывалась. Такая ситуация и называется утечкой памяти.
Если объекты, ссылки на которые теряются, создаются в программе постоянно, то утечка памяти проявляется в постепенном увеличении объёма используемой памяти; если программа работает долго, объём используемой ею памяти постоянно растёт, и через какое-то время ощутимо замедляется работа системы (из-за необходимости при любом выделении памяти использовать свопинг), либо программа исчерпывает доступный объём адресного пространства и завершается с ошибкой.

Механизм сборки мусора

Основные принципы

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

В системе со сборкой мусора обязанность освобождения памяти от объектов, которые больше не используются, возлагается на среду исполнения программы. Программист лишь создаёт динамические объекты и пользуется ими, он может не заботиться об удалении объектов, поскольку это делает за него среда. Для осуществления сборки мусора в состав среды исполнения включается специальный программный модуль, называемый «сборщиком мусора». Этот модуль периодически запускается, определяет, какие из созданных в динамической памяти объектов более не используются, и освобождает занимаемую ими память.

Периодичность запуска сборщика мусора определяется особенностями системы. Сборщик может работать в фоновом режиме, запускаясь при неактивности программы (например, когда программа простаивает, ожидая ввода данных пользователем). Сборщик мусора запускается безусловно, прерывая на время своей работы выполнение программы, когда очередную операцию выделения памяти оказывается невозможно выполнить из-за того, что вся доступная память исчерпана. После освобождения памяти прерванная операция выделения памяти возобновляется, и программа продолжает исполняться дальше. Если же оказывается, что освободить память невозможно, среда исполнения останавливает программу с сообщением об ошибке «Недостаточно памяти».

Достижимость объекта

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

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

Неформально можно задать следующее рекурсивное определение достижимого объекта:

Такое определение не является теоретически наилучшим, так как в число достижимых, согласно ему, попадают и те объекты, которые уже никогда не будут использованы, но на которые пока ещё существуют ссылки. Оптимальным было бы считать недостижимым объект, к которому в процессе дальнейшей работы программы не будет ни одного обращения, однако выявление таких объектов невозможно, поскольку сводится к алгоритмически неразрешимой задаче об остановке (для этого достаточно предположить, что некоторый объект X будет использован в том и только в том случае, если успешно завершится программа P).

Алгоритм выставления флагов

Простой алгоритм определения достижимых объектов, «алгоритм пометок» (Mark and Sweep), заключается в следующем:

(Следует обратить внимание, что, согласно данному алгоритму, если два или более объектов ссылаются друг на друга, но ни на один из этих объектов нет других ссылок, то имеет место циклическая ссылка, и вся группа считается недостижимой. Эта особенность алгоритма позволяет гарантированно удалять группы объектов, использование которых прекратилось, но в которых имеются ссылки друг на друга. Такие группы часто называются «islands of isolation» (острова изоляции))

Алгоритм подсчёта ссылок

Другой вариант алгоритма определения достижимости — обычный подсчёт ссылок. Его использование замедляет операции присваивания ссылок, но зато определение достижимых объектов тривиально — это все объекты, значение счётчика ссылок которых превышает нуль. Без дополнительных уточнений этот алгоритм, в отличие от предыдущего, не удаляет циклически замкнутые цепочки вышедших из употребления объектов, сохранивших ссылки друг на друга.

Стратегии сборки мусора

Как только определено множество недостижимых объектов, сборщик мусора может освободить память, занимаемую ими, и оставить остальное как есть. Также можно после освобождения памяти переместить все или часть оставшихся объектов в другие области памяти, обновив вместе с этим все ссылки на них. Эти два варианта реализации называются, соответственно, неперемещающим и перемещающим.

Обе стратегии имеют как достоинства, так и недостатки

Скорость выделения и освобождения памяти
Неперемещающий сборщик мусора быстрее освобождает память (поскольку эта операция сводится к пометке соответствующих блоков памяти как свободных), но тратит больше времени на её выделение (поскольку память фрагментируется, и при выделении необходимо найти в памяти нужное количество блоков подходящего размера).
Перемещающий сборщик требует сравнительно больше времени при сборе мусора (тратится дополнительное время на дефрагментацию памяти и изменение всех ссылок на перемещаемые объекты), зато перемещение позволяет использовать чрезвычайно простой и быстрый (O(1)) алгоритм выделения памяти. При дефрагментации объекты передвигаются так, чтобы разделить всю память на две большие области — занятую и свободную, и сохраняется указатель на их границу. Для выделения новой памяти достаточно лишь переместить эту границу, вернув кусок из начала свободной памяти.
Скорость доступа к объектам в динамической памяти
Объекты, поля которых используются совместно, перемещающий сборщик позволяет размещать в памяти недалеко друг от друга. Тогда они вероятнее окажутся в кэше процессора одновременно, что уменьшит количество обращений к относительно медленному ОЗУ.
Совместимость с инородным кодом
Перемещающий сборщик мусора вызывает затруднения при использовании кода, который не контролируется системой автоматического управления памятью (такой код называется инородным (англ. foreign) в традиционной терминологии или неуправляемым (англ. unmanaged) в терминологии Microsoft). Указатель на память, выделенную в системе с неперемещающим сборщиком, можно просто передать инородному коду для использования, удерживая хотя бы одну обычную ссылку на объект, чтобы сборщик его не удалил. Перемещающий сборщик меняет положение объектов в памяти, синхронно меняя все ссылки на них, но поменять ссылки в инородном коде он не может, в результате переданные инородному коду ссылки после перемещения объекта станут некорректными. Для работы с инородным кодом используются различные специальные приёмы, например, pinning — явная блокировка объекта, запрещающая его перемещение во время сборки мусора.

Поколения объектов

Как показывает практика, недавно созданные объекты чаще становятся недостижимыми, чем объекты, существующие длительное время. В соответствии с этой закономерностью многие современные сборщики мусора подразделяют все объекты на несколько поколений — серий объектов с близким временем существования. Как только память, выделенная одному из поколений, заканчивается, в этом поколении и во всех более «молодых» производится поиск недостижимых объектов. Все они удаляются, а оставшиеся переводятся в более «старое» поколение.

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

Другие механизмы

Неизменные объекты (англ. immutable objects)
Например, java.lang.String в Java. Как только строке присвоили какое-то значение, её уже нельзя менять. Подпрограммы будут передавать ссылку на эту строку друг другу, и когда все ссылки исчезнут, строка будет уничтожена сборщиком мусора.
Финализаторы
Финализатор указывает, что делать, когда объект попадает под сборщик мусора. Обычно финализаторы пишут для обёрток над объектами операционной системы (файлами, сетевыми сокетами); они автоматически закрывают соответствующий объект.
Поскольку объект до сбора может «провисеть» в памяти довольно долго, хорошая манера программирования — закрыть файл или сокет вручную, командой наподобие close().

Требования к языку и системе

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

Необходимость среды исполнения со сборщиком мусора
Естественно, для сборки мусора необходима динамическая среда, поддерживающая исполнение программы, и наличие в этой среде сборщика мусора.
Поддержка со стороны языка программирования
Сборщик мусора может нормально функционировать только тогда, когда он может точно отследить все ссылки на все созданные объекты. Очевидно, если язык допускает преобразование ссылок (указателей) в другие типы данных (целые числа, массивы байтов и так далее), такой как Си/Си++, отследить использование таких преобразованных ссылок становится невозможно, и сборка мусора становится бессмысленной — она не защищает от «повисания» ссылок и утечек памяти. Поэтому языки, ориентированные на использование сборки мусора, обычно существенно ограничивают свободу использования указателей, адресной арифметики, преобразований типов указателей к другим типам данных. В части из них вообще нет типа данных «указатель», в части он есть, но не допускает ни преобразований типа, ни изменения.
Техническая допустимость кратковременных замедлений в работе программ
Сборка мусора выполняется периодически, как правило, в заранее неизвестные моменты времени. Если приостановка работы программы на время, сравнимое со временем сборки мусора, может привести к критическим ошибкам, использовать в подобной ситуации сборку мусора, очевидно, нельзя.
Наличие некоторого резерва свободной памяти
Чем больше памяти доступно среде исполнения, тем реже запускается сборщик мусора и тем эффективнее его работа. Работа сборщика мусора в системе, где количество доступной сборщику памяти приближается к пиковой потребности программы, может оказаться неэффективной и непроизводительной. Чем меньше избыток памяти, тем чаще происходит запуск сборщика и тем больше времени тратится на его выполнение. Падение производительности программы в таком режиме может оказаться слишком существенным.

Проблемы использования

Вопреки часто встречающимся утверждениям, наличие сборки мусора вовсе не освобождает программиста от всех проблем управления памятью.

Освобождение других ресурсов, занятых объектом
Помимо динамической памяти, объект может владеть и другими ресурсами — подчас более ценными, чем память. Если объект при создании открывает файл, по завершении использования он должен его закрыть, если подключается к СУБД — должен отключиться. В системах с ручным управлением памятью это делается непосредственно перед удалением объекта из памяти, чаще всего — в деструкторах соответствующих объектов. В системах со сборкой мусора обычно есть возможность выполнить некоторый код непосредственно перед удалением объекта, так называемые финализаторы, но для освобождения ресурсов они не годятся, так как момент удаления заранее неизвестен, и может оказаться, что ресурс освобождается намного позже, чем перестаёт использоваться объект. В подобных случаях программисту всё равно приходится отслеживать использование объекта вручную и вручную выполнять операции по освобождению занятых объектом ресурсов. В C# специально для этой цели существует интерфейс IDisposable, в JavaCloseable.
Утечка памяти
В системах со сборкой мусора тоже могут возникать утечки памяти, правда, имеющие несколько другую природу. Ссылка на неиспользуемый объект может сохраниться в другом объекте, который используется и становится своеобразным «якорем», удерживающим ненужный объект в памяти. Например, созданный объект добавляется в коллекцию, используемую для вспомогательных операций, потом перестаёт использоваться, но не удаляется из коллекции. Коллекция удерживает ссылку, объект остаётся достижимым и не подвергается сборке мусора. Результатом становится всё та же утечка памяти.
Чтобы устранить подобные проблемы, среда исполнения может поддерживать специальное средство — так называемые слабые ссылки. Слабые ссылки не удерживают объекта и превращаются в null, как только объект исчезает — поэтому код должен быть готов к тому, что однажды ссылка укажет в никуда.

Достоинства и недостатки

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

Например, объект никогда не будет удалён, если на него остался хотя бы один необнулённый указатель в глобальной области видимости, и поиск такой псевдоутечки в языках со сборщиком мусора особенно сложен. Программист не может полностью игнорировать вопрос управления памятью при наличии сборщика мусора, хотя затраты ручного труда на управление памятью в этом случае всё-таки существенно меньше по сравнению с языками с полностью ручным управлением (без сборщика и автодеструкторов). Зачастую критически важной является не только гарантия освобождения ресурса, но и гарантия того, что он освободится до вызова какой-то другой процедуры — например, открытые файлы, входы в критические секции. Отдавать управление этими ресурсами сборщику мусора нельзя, поэтому приходится убирать их вручную. Впрочем, в последнее время даже в языках со сборщиком мусора вводят возможность создавать классы с детерминированным вызовом специального метода-«деструктора» (Dispose) при выходе из зоны видимости.

Во многих случаях системы со сборкой мусора демонстрируют меньшую эффективность, как по скорости, так и по объёму используемой памяти (что неизбежно, так как сборщик мусора сам потребляет ресурсы и нуждается в некотором избытке свободной памяти для нормальной работы). Кроме того, в системах со сборкой мусора сложнее реализуются низкоуровневые алгоритмы, требующие прямого доступа к оперативной памяти компьютера, поскольку свободное использование указателей невозможно, и прямой доступ к памяти требует наличия специальных интерфейсов, написанных на низкоуровневых языках. С другой стороны, в современных системах со сборкой мусора операция выделения памяти сведена к элементарному добавлению блока в конец кучи, причём куча время от времени уплотняется, уменьшая фрагментацию данных.

Поддержка в некоторых императивных языках автоматического вызова деструктора (C++[4], Ада, Delphi), а также более простая, чем сборка мусора, технология использования «умных ссылок» (отслеживания количества ссылок на объект непосредственно в нём и автоматическое удаление при удалении последней ссылки, как это сделано в технологии COM) значительно снижает вероятность утечек, позволяя концентрировать опасные места внутри реализации класса, при этом не требуя лишних ресурсов, хотя и требует при этом более высокой квалификации программиста. Конечно, писать код освобождения ресурсов всё равно придётся, но автоматические деструкторы дадут уверенность, что этот код обязательно вызовется. Впрочем, для наиболее часто используемых ресурсов во всех популярных языках, поддерживающих автодеструкторы, уже есть автоматические обёртки, которые сами закрывают ресурс, благодаря чему забота о ресурсах становится едва ли не проще, чем с непредсказуемым сборщиком мусора.

Существенное удобство от сборки мусора возникает тогда, когда динамически созданные объекты живут длительное время, многократно дублируются, а ссылки на них передаются между различными участками программы. В таких программах в общем случае достаточно сложно безошибочно определить место, где объект перестал использоваться и его можно удалять. Поскольку именно такая ситуация складывается при широком использовании динамически изменяемых структур данных (списки, деревья, графы), сборка мусора является необходимой в широко использующих такие структуры функциональных и логических языках, типа Хаскелла, Лиспа или Пролога. Использование сборки мусора в традиционных императивных языках (основанных на структурной парадигме, возможно, дополненной объектными средствами) определяется желаемым соотношением между простотой и скоростью разработки программ и эффективностью её выполнения.

Управление памятью в конкретных языках и системах

Сборка мусора часто противопоставляется ручному управлению памятью, при котором программист явно указывает, когда и какие области памяти надо освободить. Однако есть языки, в которых используется комбинация двух методов управления памятью, равно как есть и другие технологии решения той же фундаментальной проблемы (например, en:region inference).

Некоторые языки программирования требуют использования механизма сборки мусора в соответствии со своей спецификацией (Java, C#, Eiffel), другие — по причинам эффективности реализации (например, формальные языки для лямбда-исчисления) — эти языки называются языками со сборкой мусора. Многие языки со сборкой мусора не имеют возможностей для явного ручного удаления объектов (например, оператора delete), благодаря чему возникновение висячих ссылок исключается в принципе, а сборщик мусора лишь занимается удалением объектов, на которые нет ссылок из программы.

Некоторые языки (например, Modula-3) позволяют использовать как ручное управление памятью, так и сборку мусора в одном приложении — используя две отдельные кучи.

См. также

Напишите отзыв о статье "Сборка мусора"

Примечания

  1. [www.lingvo-online.ru/ru/Examples/en-ru/garbage%20collection Выдержка из словарей ABBYY Lingvo]
  2. Словарь Ушакова: [slovari.yandex.ru/сбор/правописание/ сбор](недоступная ссылка с 14-06-2016 (2872 дня)), [slovari.yandex.ru/сборка/правописание/ сборка](недоступная ссылка с 14-06-2016 (2872 дня))
  3. Реймонд Чен. [www.transl-gunsmoker.ru/2012/09/blog-post.html Наверняка вы думаете о сборке мусора неправильно]
  4. [www.codeproject.com/Articles/10141/RAII-Dynamic-Objects-and-Factories-in-C#1 RAII, Dynamic Objects, and Factories in C++, Roland Pibinger, 3 May 2005]


Отрывок, характеризующий Сборка мусора

Маршалы и генералы, находившиеся в более близком расстоянии от поля сражения, но так же, как и Наполеон, не участвовавшие в самом сражении и только изредка заезжавшие под огонь пуль, не спрашиваясь Наполеона, делали свои распоряжения и отдавали свои приказания о том, куда и откуда стрелять, и куда скакать конным, и куда бежать пешим солдатам. Но даже и их распоряжения, точно так же как распоряжения Наполеона, точно так же в самой малой степени и редко приводились в исполнение. Большей частью выходило противное тому, что они приказывали. Солдаты, которым велено было идти вперед, подпав под картечный выстрел, бежали назад; солдаты, которым велено было стоять на месте, вдруг, видя против себя неожиданно показавшихся русских, иногда бежали назад, иногда бросались вперед, и конница скакала без приказания догонять бегущих русских. Так, два полка кавалерии поскакали через Семеновский овраг и только что въехали на гору, повернулись и во весь дух поскакали назад. Так же двигались и пехотные солдаты, иногда забегая совсем не туда, куда им велено было. Все распоряжение о том, куда и когда подвинуть пушки, когда послать пеших солдат – стрелять, когда конных – топтать русских пеших, – все эти распоряжения делали сами ближайшие начальники частей, бывшие в рядах, не спрашиваясь даже Нея, Даву и Мюрата, не только Наполеона. Они не боялись взыскания за неисполнение приказания или за самовольное распоряжение, потому что в сражении дело касается самого дорогого для человека – собственной жизни, и иногда кажется, что спасение заключается в бегстве назад, иногда в бегстве вперед, и сообразно с настроением минуты поступали эти люди, находившиеся в самом пылу сражения. В сущности же, все эти движения вперед и назад не облегчали и не изменяли положения войск. Все их набегания и наскакивания друг на друга почти не производили им вреда, а вред, смерть и увечья наносили ядра и пули, летавшие везде по тому пространству, по которому метались эти люди. Как только эти люди выходили из того пространства, по которому летали ядра и пули, так их тотчас же стоявшие сзади начальники формировали, подчиняли дисциплине и под влиянием этой дисциплины вводили опять в область огня, в которой они опять (под влиянием страха смерти) теряли дисциплину и метались по случайному настроению толпы.


Генералы Наполеона – Даву, Ней и Мюрат, находившиеся в близости этой области огня и даже иногда заезжавшие в нее, несколько раз вводили в эту область огня стройные и огромные массы войск. Но противно тому, что неизменно совершалось во всех прежних сражениях, вместо ожидаемого известия о бегстве неприятеля, стройные массы войск возвращались оттуда расстроенными, испуганными толпами. Они вновь устроивали их, но людей все становилось меньше. В половине дня Мюрат послал к Наполеону своего адъютанта с требованием подкрепления.
Наполеон сидел под курганом и пил пунш, когда к нему прискакал адъютант Мюрата с уверениями, что русские будут разбиты, ежели его величество даст еще дивизию.
– Подкрепления? – сказал Наполеон с строгим удивлением, как бы не понимая его слов и глядя на красивого мальчика адъютанта с длинными завитыми черными волосами (так же, как носил волоса Мюрат). «Подкрепления! – подумал Наполеон. – Какого они просят подкрепления, когда у них в руках половина армии, направленной на слабое, неукрепленное крыло русских!»
– Dites au roi de Naples, – строго сказал Наполеон, – qu'il n'est pas midi et que je ne vois pas encore clair sur mon echiquier. Allez… [Скажите неаполитанскому королю, что теперь еще не полдень и что я еще не ясно вижу на своей шахматной доске. Ступайте…]
Красивый мальчик адъютанта с длинными волосами, не отпуская руки от шляпы, тяжело вздохнув, поскакал опять туда, где убивали людей.
Наполеон встал и, подозвав Коленкура и Бертье, стал разговаривать с ними о делах, не касающихся сражения.
В середине разговора, который начинал занимать Наполеона, глаза Бертье обратились на генерала с свитой, который на потной лошади скакал к кургану. Это был Бельяр. Он, слезши с лошади, быстрыми шагами подошел к императору и смело, громким голосом стал доказывать необходимость подкреплений. Он клялся честью, что русские погибли, ежели император даст еще дивизию.
Наполеон вздернул плечами и, ничего не ответив, продолжал свою прогулку. Бельяр громко и оживленно стал говорить с генералами свиты, окружившими его.
– Вы очень пылки, Бельяр, – сказал Наполеон, опять подходя к подъехавшему генералу. – Легко ошибиться в пылу огня. Поезжайте и посмотрите, и тогда приезжайте ко мне.
Не успел еще Бельяр скрыться из вида, как с другой стороны прискакал новый посланный с поля сражения.
– Eh bien, qu'est ce qu'il y a? [Ну, что еще?] – сказал Наполеон тоном человека, раздраженного беспрестанными помехами.
– Sire, le prince… [Государь, герцог…] – начал адъютант.
– Просит подкрепления? – с гневным жестом проговорил Наполеон. Адъютант утвердительно наклонил голову и стал докладывать; но император отвернулся от него, сделав два шага, остановился, вернулся назад и подозвал Бертье. – Надо дать резервы, – сказал он, слегка разводя руками. – Кого послать туда, как вы думаете? – обратился он к Бертье, к этому oison que j'ai fait aigle [гусенку, которого я сделал орлом], как он впоследствии называл его.
– Государь, послать дивизию Клапареда? – сказал Бертье, помнивший наизусть все дивизии, полки и батальоны.
Наполеон утвердительно кивнул головой.
Адъютант поскакал к дивизии Клапареда. И чрез несколько минут молодая гвардия, стоявшая позади кургана, тронулась с своего места. Наполеон молча смотрел по этому направлению.
– Нет, – обратился он вдруг к Бертье, – я не могу послать Клапареда. Пошлите дивизию Фриана, – сказал он.
Хотя не было никакого преимущества в том, чтобы вместо Клапареда посылать дивизию Фриана, и даже было очевидное неудобство и замедление в том, чтобы остановить теперь Клапареда и посылать Фриана, но приказание было с точностью исполнено. Наполеон не видел того, что он в отношении своих войск играл роль доктора, который мешает своими лекарствами, – роль, которую он так верно понимал и осуждал.
Дивизия Фриана, так же как и другие, скрылась в дыму поля сражения. С разных сторон продолжали прискакивать адъютанты, и все, как бы сговорившись, говорили одно и то же. Все просили подкреплений, все говорили, что русские держатся на своих местах и производят un feu d'enfer [адский огонь], от которого тает французское войско.
Наполеон сидел в задумчивости на складном стуле.
Проголодавшийся с утра m r de Beausset, любивший путешествовать, подошел к императору и осмелился почтительно предложить его величеству позавтракать.
– Я надеюсь, что теперь уже я могу поздравить ваше величество с победой, – сказал он.
Наполеон молча отрицательно покачал головой. Полагая, что отрицание относится к победе, а не к завтраку, m r de Beausset позволил себе игриво почтительно заметить, что нет в мире причин, которые могли бы помешать завтракать, когда можно это сделать.
– Allez vous… [Убирайтесь к…] – вдруг мрачно сказал Наполеон и отвернулся. Блаженная улыбка сожаления, раскаяния и восторга просияла на лице господина Боссе, и он плывущим шагом отошел к другим генералам.
Наполеон испытывал тяжелое чувство, подобное тому, которое испытывает всегда счастливый игрок, безумно кидавший свои деньги, всегда выигрывавший и вдруг, именно тогда, когда он рассчитал все случайности игры, чувствующий, что чем более обдуман его ход, тем вернее он проигрывает.
Войска были те же, генералы те же, те же были приготовления, та же диспозиция, та же proclamation courte et energique [прокламация короткая и энергическая], он сам был тот же, он это знал, он знал, что он был даже гораздо опытнее и искуснее теперь, чем он был прежде, даже враг был тот же, как под Аустерлицем и Фридландом; но страшный размах руки падал волшебно бессильно.
Все те прежние приемы, бывало, неизменно увенчиваемые успехом: и сосредоточение батарей на один пункт, и атака резервов для прорвания линии, и атака кавалерии des hommes de fer [железных людей], – все эти приемы уже были употреблены, и не только не было победы, но со всех сторон приходили одни и те же известия об убитых и раненых генералах, о необходимости подкреплений, о невозможности сбить русских и о расстройстве войск.
Прежде после двух трех распоряжений, двух трех фраз скакали с поздравлениями и веселыми лицами маршалы и адъютанты, объявляя трофеями корпуса пленных, des faisceaux de drapeaux et d'aigles ennemis, [пуки неприятельских орлов и знамен,] и пушки, и обозы, и Мюрат просил только позволения пускать кавалерию для забрания обозов. Так было под Лоди, Маренго, Арколем, Иеной, Аустерлицем, Ваграмом и так далее, и так далее. Теперь же что то странное происходило с его войсками.
Несмотря на известие о взятии флешей, Наполеон видел, что это было не то, совсем не то, что было во всех его прежних сражениях. Он видел, что то же чувство, которое испытывал он, испытывали и все его окружающие люди, опытные в деле сражений. Все лица были печальны, все глаза избегали друг друга. Только один Боссе не мог понимать значения того, что совершалось. Наполеон же после своего долгого опыта войны знал хорошо, что значило в продолжение восьми часов, после всех употрсбленных усилий, невыигранное атакующим сражение. Он знал, что это было почти проигранное сражение и что малейшая случайность могла теперь – на той натянутой точке колебания, на которой стояло сражение, – погубить его и его войска.
Когда он перебирал в воображении всю эту странную русскую кампанию, в которой не было выиграно ни одного сраженья, в которой в два месяца не взято ни знамен, ни пушек, ни корпусов войск, когда глядел на скрытно печальные лица окружающих и слушал донесения о том, что русские всё стоят, – страшное чувство, подобное чувству, испытываемому в сновидениях, охватывало его, и ему приходили в голову все несчастные случайности, могущие погубить его. Русские могли напасть на его левое крыло, могли разорвать его середину, шальное ядро могло убить его самого. Все это было возможно. В прежних сражениях своих он обдумывал только случайности успеха, теперь же бесчисленное количество несчастных случайностей представлялось ему, и он ожидал их всех. Да, это было как во сне, когда человеку представляется наступающий на него злодей, и человек во сне размахнулся и ударил своего злодея с тем страшным усилием, которое, он знает, должно уничтожить его, и чувствует, что рука его, бессильная и мягкая, падает, как тряпка, и ужас неотразимой погибели обхватывает беспомощного человека.
Известие о том, что русские атакуют левый фланг французской армии, возбудило в Наполеоне этот ужас. Он молча сидел под курганом на складном стуле, опустив голову и положив локти на колена. Бертье подошел к нему и предложил проехаться по линии, чтобы убедиться, в каком положении находилось дело.
– Что? Что вы говорите? – сказал Наполеон. – Да, велите подать мне лошадь.
Он сел верхом и поехал к Семеновскому.
В медленно расходившемся пороховом дыме по всему тому пространству, по которому ехал Наполеон, – в лужах крови лежали лошади и люди, поодиночке и кучами. Подобного ужаса, такого количества убитых на таком малом пространстве никогда не видал еще и Наполеон, и никто из его генералов. Гул орудий, не перестававший десять часов сряду и измучивший ухо, придавал особенную значительность зрелищу (как музыка при живых картинах). Наполеон выехал на высоту Семеновского и сквозь дым увидал ряды людей в мундирах цветов, непривычных для его глаз. Это были русские.
Русские плотными рядами стояли позади Семеновского и кургана, и их орудия не переставая гудели и дымили по их линии. Сражения уже не было. Было продолжавшееся убийство, которое ни к чему не могло повести ни русских, ни французов. Наполеон остановил лошадь и впал опять в ту задумчивость, из которой вывел его Бертье; он не мог остановить того дела, которое делалось перед ним и вокруг него и которое считалось руководимым им и зависящим от него, и дело это ему в первый раз, вследствие неуспеха, представлялось ненужным и ужасным.
Один из генералов, подъехавших к Наполеону, позволил себе предложить ему ввести в дело старую гвардию. Ней и Бертье, стоявшие подле Наполеона, переглянулись между собой и презрительно улыбнулись на бессмысленное предложение этого генерала.
Наполеон опустил голову и долго молчал.
– A huit cent lieux de France je ne ferai pas demolir ma garde, [За три тысячи двести верст от Франции я не могу дать разгромить свою гвардию.] – сказал он и, повернув лошадь, поехал назад, к Шевардину.


Кутузов сидел, понурив седую голову и опустившись тяжелым телом, на покрытой ковром лавке, на том самом месте, на котором утром его видел Пьер. Он не делал никаких распоряжении, а только соглашался или не соглашался на то, что предлагали ему.
«Да, да, сделайте это, – отвечал он на различные предложения. – Да, да, съезди, голубчик, посмотри, – обращался он то к тому, то к другому из приближенных; или: – Нет, не надо, лучше подождем», – говорил он. Он выслушивал привозимые ему донесения, отдавал приказания, когда это требовалось подчиненным; но, выслушивая донесения, он, казалось, не интересовался смыслом слов того, что ему говорили, а что то другое в выражении лиц, в тоне речи доносивших интересовало его. Долголетним военным опытом он знал и старческим умом понимал, что руководить сотнями тысяч человек, борющихся с смертью, нельзя одному человеку, и знал, что решают участь сраженья не распоряжения главнокомандующего, не место, на котором стоят войска, не количество пушек и убитых людей, а та неуловимая сила, называемая духом войска, и он следил за этой силой и руководил ею, насколько это было в его власти.
Общее выражение лица Кутузова было сосредоточенное, спокойное внимание и напряжение, едва превозмогавшее усталость слабого и старого тела.
В одиннадцать часов утра ему привезли известие о том, что занятые французами флеши были опять отбиты, но что князь Багратион ранен. Кутузов ахнул и покачал головой.
– Поезжай к князю Петру Ивановичу и подробно узнай, что и как, – сказал он одному из адъютантов и вслед за тем обратился к принцу Виртембергскому, стоявшему позади него:
– Не угодно ли будет вашему высочеству принять командование первой армией.
Вскоре после отъезда принца, так скоро, что он еще не мог доехать до Семеновского, адъютант принца вернулся от него и доложил светлейшему, что принц просит войск.
Кутузов поморщился и послал Дохтурову приказание принять командование первой армией, а принца, без которого, как он сказал, он не может обойтись в эти важные минуты, просил вернуться к себе. Когда привезено было известие о взятии в плен Мюрата и штабные поздравляли Кутузова, он улыбнулся.
– Подождите, господа, – сказал он. – Сражение выиграно, и в пленении Мюрата нет ничего необыкновенного. Но лучше подождать радоваться. – Однако он послал адъютанта проехать по войскам с этим известием.
Когда с левого фланга прискакал Щербинин с донесением о занятии французами флешей и Семеновского, Кутузов, по звукам поля сражения и по лицу Щербинина угадав, что известия были нехорошие, встал, как бы разминая ноги, и, взяв под руку Щербинина, отвел его в сторону.
– Съезди, голубчик, – сказал он Ермолову, – посмотри, нельзя ли что сделать.
Кутузов был в Горках, в центре позиции русского войска. Направленная Наполеоном атака на наш левый фланг была несколько раз отбиваема. В центре французы не подвинулись далее Бородина. С левого фланга кавалерия Уварова заставила бежать французов.
В третьем часу атаки французов прекратились. На всех лицах, приезжавших с поля сражения, и на тех, которые стояли вокруг него, Кутузов читал выражение напряженности, дошедшей до высшей степени. Кутузов был доволен успехом дня сверх ожидания. Но физические силы оставляли старика. Несколько раз голова его низко опускалась, как бы падая, и он задремывал. Ему подали обедать.
Флигель адъютант Вольцоген, тот самый, который, проезжая мимо князя Андрея, говорил, что войну надо im Raum verlegon [перенести в пространство (нем.) ], и которого так ненавидел Багратион, во время обеда подъехал к Кутузову. Вольцоген приехал от Барклая с донесением о ходе дел на левом фланге. Благоразумный Барклай де Толли, видя толпы отбегающих раненых и расстроенные зады армии, взвесив все обстоятельства дела, решил, что сражение было проиграно, и с этим известием прислал к главнокомандующему своего любимца.
Кутузов с трудом жевал жареную курицу и сузившимися, повеселевшими глазами взглянул на Вольцогена.
Вольцоген, небрежно разминая ноги, с полупрезрительной улыбкой на губах, подошел к Кутузову, слегка дотронувшись до козырька рукою.
Вольцоген обращался с светлейшим с некоторой аффектированной небрежностью, имеющей целью показать, что он, как высокообразованный военный, предоставляет русским делать кумира из этого старого, бесполезного человека, а сам знает, с кем он имеет дело. «Der alte Herr (как называли Кутузова в своем кругу немцы) macht sich ganz bequem, [Старый господин покойно устроился (нем.) ] – подумал Вольцоген и, строго взглянув на тарелки, стоявшие перед Кутузовым, начал докладывать старому господину положение дел на левом фланге так, как приказал ему Барклай и как он сам его видел и понял.
– Все пункты нашей позиции в руках неприятеля и отбить нечем, потому что войск нет; они бегут, и нет возможности остановить их, – докладывал он.
Кутузов, остановившись жевать, удивленно, как будто не понимая того, что ему говорили, уставился на Вольцогена. Вольцоген, заметив волнение des alten Herrn, [старого господина (нем.) ] с улыбкой сказал:
– Я не считал себя вправе скрыть от вашей светлости того, что я видел… Войска в полном расстройстве…
– Вы видели? Вы видели?.. – нахмурившись, закричал Кутузов, быстро вставая и наступая на Вольцогена. – Как вы… как вы смеете!.. – делая угрожающие жесты трясущимися руками и захлебываясь, закричал он. – Как смоете вы, милостивый государь, говорить это мне. Вы ничего не знаете. Передайте от меня генералу Барклаю, что его сведения неверны и что настоящий ход сражения известен мне, главнокомандующему, лучше, чем ему.
Вольцоген хотел возразить что то, но Кутузов перебил его.
– Неприятель отбит на левом и поражен на правом фланге. Ежели вы плохо видели, милостивый государь, то не позволяйте себе говорить того, чего вы не знаете. Извольте ехать к генералу Барклаю и передать ему назавтра мое непременное намерение атаковать неприятеля, – строго сказал Кутузов. Все молчали, и слышно было одно тяжелое дыхание запыхавшегося старого генерала. – Отбиты везде, за что я благодарю бога и наше храброе войско. Неприятель побежден, и завтра погоним его из священной земли русской, – сказал Кутузов, крестясь; и вдруг всхлипнул от наступивших слез. Вольцоген, пожав плечами и скривив губы, молча отошел к стороне, удивляясь uber diese Eingenommenheit des alten Herrn. [на это самодурство старого господина. (нем.) ]
– Да, вот он, мой герой, – сказал Кутузов к полному красивому черноволосому генералу, который в это время входил на курган. Это был Раевский, проведший весь день на главном пункте Бородинского поля.
Раевский доносил, что войска твердо стоят на своих местах и что французы не смеют атаковать более. Выслушав его, Кутузов по французски сказал:
– Vous ne pensez donc pas comme lesautres que nous sommes obliges de nous retirer? [Вы, стало быть, не думаете, как другие, что мы должны отступить?]
– Au contraire, votre altesse, dans les affaires indecises c'est loujours le plus opiniatre qui reste victorieux, – отвечал Раевский, – et mon opinion… [Напротив, ваша светлость, в нерешительных делах остается победителем тот, кто упрямее, и мое мнение…]
– Кайсаров! – крикнул Кутузов своего адъютанта. – Садись пиши приказ на завтрашний день. А ты, – обратился он к другому, – поезжай по линии и объяви, что завтра мы атакуем.
Пока шел разговор с Раевским и диктовался приказ, Вольцоген вернулся от Барклая и доложил, что генерал Барклай де Толли желал бы иметь письменное подтверждение того приказа, который отдавал фельдмаршал.
Кутузов, не глядя на Вольцогена, приказал написать этот приказ, который, весьма основательно, для избежания личной ответственности, желал иметь бывший главнокомандующий.
И по неопределимой, таинственной связи, поддерживающей во всей армии одно и то же настроение, называемое духом армии и составляющее главный нерв войны, слова Кутузова, его приказ к сражению на завтрашний день, передались одновременно во все концы войска.
Далеко не самые слова, не самый приказ передавались в последней цепи этой связи. Даже ничего не было похожего в тех рассказах, которые передавали друг другу на разных концах армии, на то, что сказал Кутузов; но смысл его слов сообщился повсюду, потому что то, что сказал Кутузов, вытекало не из хитрых соображений, а из чувства, которое лежало в душе главнокомандующего, так же как и в душе каждого русского человека.
И узнав то, что назавтра мы атакуем неприятеля, из высших сфер армии услыхав подтверждение того, чему они хотели верить, измученные, колеблющиеся люди утешались и ободрялись.


Полк князя Андрея был в резервах, которые до второго часа стояли позади Семеновского в бездействии, под сильным огнем артиллерии. Во втором часу полк, потерявший уже более двухсот человек, был двинут вперед на стоптанное овсяное поле, на тот промежуток между Семеновским и курганной батареей, на котором в этот день были побиты тысячи людей и на который во втором часу дня был направлен усиленно сосредоточенный огонь из нескольких сот неприятельских орудий.
Не сходя с этого места и не выпустив ни одного заряда, полк потерял здесь еще третью часть своих людей. Спереди и в особенности с правой стороны, в нерасходившемся дыму, бубухали пушки и из таинственной области дыма, застилавшей всю местность впереди, не переставая, с шипящим быстрым свистом, вылетали ядра и медлительно свистевшие гранаты. Иногда, как бы давая отдых, проходило четверть часа, во время которых все ядра и гранаты перелетали, но иногда в продолжение минуты несколько человек вырывало из полка, и беспрестанно оттаскивали убитых и уносили раненых.
С каждым новым ударом все меньше и меньше случайностей жизни оставалось для тех, которые еще не были убиты. Полк стоял в батальонных колоннах на расстоянии трехсот шагов, но, несмотря на то, все люди полка находились под влиянием одного и того же настроения. Все люди полка одинаково были молчаливы и мрачны. Редко слышался между рядами говор, но говор этот замолкал всякий раз, как слышался попавший удар и крик: «Носилки!» Большую часть времени люди полка по приказанию начальства сидели на земле. Кто, сняв кивер, старательно распускал и опять собирал сборки; кто сухой глиной, распорошив ее в ладонях, начищал штык; кто разминал ремень и перетягивал пряжку перевязи; кто старательно расправлял и перегибал по новому подвертки и переобувался. Некоторые строили домики из калмыжек пашни или плели плетеночки из соломы жнивья. Все казались вполне погружены в эти занятия. Когда ранило и убивало людей, когда тянулись носилки, когда наши возвращались назад, когда виднелись сквозь дым большие массы неприятелей, никто не обращал никакого внимания на эти обстоятельства. Когда же вперед проезжала артиллерия, кавалерия, виднелись движения нашей пехоты, одобрительные замечания слышались со всех сторон. Но самое большое внимание заслуживали события совершенно посторонние, не имевшие никакого отношения к сражению. Как будто внимание этих нравственно измученных людей отдыхало на этих обычных, житейских событиях. Батарея артиллерии прошла пред фронтом полка. В одном из артиллерийских ящиков пристяжная заступила постромку. «Эй, пристяжную то!.. Выправь! Упадет… Эх, не видят!.. – по всему полку одинаково кричали из рядов. В другой раз общее внимание обратила небольшая коричневая собачонка с твердо поднятым хвостом, которая, бог знает откуда взявшись, озабоченной рысцой выбежала перед ряды и вдруг от близко ударившего ядра взвизгнула и, поджав хвост, бросилась в сторону. По всему полку раздалось гоготанье и взвизги. Но развлечения такого рода продолжались минуты, а люди уже более восьми часов стояли без еды и без дела под непроходящим ужасом смерти, и бледные и нахмуренные лица все более бледнели и хмурились.