Анатомия программы в памяти
Управление памятью – одна из главных задач ОС. Она критична как для программирования, так и для системного администрирования. Я постараюсь объяснить, как ОС работает с памятью. Концепции будут общего характера, а примеры я возьму из Linux и Windows на 32-bit x86. Сначала я опишу, как программы располагаются в памяти.
Каждый процесс в многозадачной ОС работает в своей «песочнице» в памяти. Это виртуальное адресное пространство, которое в 32-битном режиме представляет собою 4Гб блок адресов. Эти виртуальные адреса ставятся в соответствие (mapping) физической памяти таблицами страниц, которые поддерживает ядро ОС. У каждого процесса есть свой набор таблиц. Но если мы начинаем использовать виртуальную адресацию, приходится использовать её для всех программ, работающих на компьютере – включая и само ядро. Поэтому часть пространства виртуальных адресов необходимо резервировать под ядро.

Это не значит, что ядро использует так много физической памяти – просто у него в распоряжении находится часть адресного пространства, которое можно поставить в соответствие необходимому количеству физической памяти. Пространство памяти для ядра отмечено в таблицах страниц как эксклюзивно используемое привилегированным кодом, поэтому если какая-то программа пытается получить в него доступ, случается page fault. В Linux пространство памяти для ядра присутствует постоянно, и ставит в соответствие одну и ту же часть физической памяти у всех процессов. Код ядра и данные всегда имеют адреса, и готовы обрабатывать прерывания и системные вызовы в любой момент. Для пользовательских программ, напротив, соответствие виртуальных адресов реальной памяти меняется, когда происходит переключение процессов:

Голубым отмечены виртуальные адреса, соответствующие физической памяти. Белым – пространство, которому не назначены адреса. В нашем примере Firefox использует гораздо больше места в виртуальной памяти из-за своей легендарной прожорливости. Полоски в адресном пространстве соответствуют сегментам памяти таким, как куча, стек и проч. Эти сегменты – всего лишь интервалы адресов памяти, и не имеют ничего общего с сегментами от Intel. Вот стандартная схема сегментов у процесса под Linux:

Когда программирование было белым и пушистым, начальные виртуальные адреса сегментов были одинаковыми для всех процессов. Это позволяло легко удалённо эксплуатировать уязвимости в безопасности. Зловредной программе часто необходимо обращаться к памяти по абсолютным адресам – адресу стека, адресу библиотечной функции, и т.п. Удаленные атаки приходилось делать вслепую, рассчитывая на то, что все адресные пространства остаются на постоянных адресах. В связи с этим получила популярность система выбора случайных адресов. Linux делает случайными стек, сегмент отображения в память и кучу, добавляя смещения к их начальным адресам. К сожалению, в 32-битном адресном пространстве особо не развернёшься, и для назначения случайных адресов остаётся мало места, что делает эту систему не слишком эффективной.
Самый верхний сегмент в адресном пространстве процесса – это стек, в большинстве языков хранящий локальные переменные и аргументы функций. Вызов метода или функции добавляет новый кадр стека (stack frame) к существующему стеку. После возврата из функции кадр уничтожается. Эта простая схема приводит к тому, что для отслеживания содержимого стека не требуется никакой сложной структуры – достаточно всего лишь указателя на начало стека. Добавление и удаление данных становится простым и однозначным процессом. Постоянное повторное использование районов памяти для стека приводит к кэшированию этих частей в CPU, что добавляет скорости. Каждый поток выполнения (thread) в процессе получает свой собственный стек.
Можно прийти к такой ситуации, в которой память, отведённая под стек, заканчивается. Это приводит к ошибке page fault, которая в Linux обрабатывается функцией expand_stack(), которая, в свою очередь, вызывает acct_stack_growth(), чтобы проверить, можно ли ещё нарастить стек. Если его размер не превышает RLIMIT_STACK (обычно это 8 Мб), то стек увеличивается и программа продолжает исполнение, как ни в чём не бывало. Но если максимальный размер стека достигнут, мы получаем переполнение стека (stack overflow) и программе приходит ошибка Segmentation Fault (ошибка сегментации). При этом стек умеет только увеличиваться – подобно государственному бюджету, он не уменьшается обратно.
Динамический рост стека – единственная ситуация, в которой может осуществляться доступ к свободной памяти, которая показана белым на схеме. Все другие попытки доступа к этой памяти вызывают ошибку page fault, приводящую к Segmentation Fault. А некоторые занятые области памяти служат только для чтения, поэтому попытки записи в эти области также приводят к Segmentation Fault.
После стека идёт сегмент отображения в память. Тут ядро размещает содержимое файлов напрямую в памяти. Любое приложение может запросить сделать это через системный вызов mmap() в Linux или CreateFileMapping() / MapViewOfFile() в Windows. Это удобный и быстрый способ организации операций ввода и вывода в файлы, поэтому он используется для подгрузки динамических библиотек. Также возможно создать анонимное место в памяти, не связанное с файлами, которое будет использоваться для данных программы. Если вы сделаете в Linux запрос на большой объём памяти через malloc(), библиотека C создаст такую анонимное отображение вместо использования памяти из кучи. Под «большим» подразумевается объём больший, чем MMAP_THRESHOLD (128 kB по умолчанию, он настраивается через mallopt().)
Сама куча расположена на следующих позициях в памяти. Она обеспечивает выделение памяти во время выполнения программы, как и стек – но, в отличие от него, хранит те данные, которые должны пережить функцию, размещающую их. В большинстве языков есть инструменты для управления кучей. В этом случае удовлетворение запроса на размещение памяти выполняется совместно программой и ядром. В С интерфейсом для работы с кучей служит malloc() с друзьями, а в языке, имеющем автоматическую сборку мусора, типа С#, интерфейсом служит ключевое слово new.
Если в куче оказывается недостаточно места для выполнения запроса, эту проблему может обработать сама программа без вмешательства ядра. В ином случае куча увеличивается системным вызовом brk(). Управление кучей – дело сложное, оно требует хитроумных алгоритмов, которые стремятся работать быстро и эффективно, чтобы угодить хаотичному методу размещению данных, которым пользуется программа. Время на обработку запроса к куче может варьироваться в широких пределах. В системах реального времени есть специальные инструменты для работы с ней. Кучи тоже бывают фрагментированными:

И вот мы добрались до самой нижней части схемы – BSS, данные и текст программы. BSS и данные хранят статичные (глобальные) переменные в С. Разница в том, что BSS хранит содержимое непроинициализированных статичных переменных, чьи значения не были заданы программистом. Кроме этого, область BSS анонимна, она не соответствует никакому файлу. Если вы пишете static int cntActiveUsers , то содержимое cntActiveUsers живёт в BSS.
Сегмент данных, наоборот, содержит те переменные, которые были проинициализированы в коде. Эта часть памяти соответствует бинарному образу программы, содержащему начальные статические значения, заданные в коде. Если вы пишете static int cntWorkerBees = 10 , то содержимое cntWorkerBees живёт в сегменте данных, и начинает свою жизнь как 10. Но, хотя сегмент данных соответствует файлу программы, это приватное отображение в память (private memory mapping) – а это значит, что обновления памяти не отражаются в соответствующем файле. Иначе изменения значения переменных отражались бы в файле, хранящемся на диске.
Пример данных на диаграмме будет немного сложнее, поскольку он использует указатель. В этом случае содержимое указателя, 4-байтный адрес памяти, живёт в сегменте данных. А строка, на которую он показывает, живёт в сегменте текста, который предназначен только для чтения. Там хранится весь код и разные другие детали, включая строковые литералы. Также он хранит ваш бинарник в памяти. Попытки записи в этот сегмент оканчиваются ошибкой Segmentation Fault. Это предотвращает ошибки, связанные с указателями (хотя не так эффективно, как если бы вы вообще не использовали язык С). На диаграмме показаны эти сегменты и примеры переменных:

Изучить области памяти Linux-процесса можно, прочитав файл /proc/pid_of_process/maps. Учтите, что один сегмент может содержать много областей. К примеру, у каждого файла, сдублированного в память, есть своя область в сегменте mmap, а у динамических библиотек – дополнительные области, напоминающие BSS и данные. Кстати, иногда, когда люди говорят «сегмент данных», они имеют в виду данные + bss + кучу.
Бинарные образы можно изучать при помощи команд nm и objdump – вы увидите символы, их адреса, сегменты, и т.п. Схема виртуальных адресов, описанная в этой статье – это т.н. «гибкая» схема, которая по умолчанию используется уже несколько лет. Она подразумевает, что переменной RLIMIT_STACK присвоено какое-то значение. В противном случае Linux использует «классическую» схему:
Какие файлы и настройки стоит сохранить перед переустановкой Windows 10 и Windows 11
У каждого из нас при использовании компьютера накапливаются файлы, которые не хотелось бы потерять при переустановке Windows 10 и 11. Даже если компьютер используется только для игр, потерять игровые сохранения игры, которую вы проходили пару месяцев — это маленькая трагедия. Куда большая трагедия может произойти, если компьютер используется для работы и после переустановки Windows выясняется, что на «Рабочем столе» лежала, к примеру, дипломная работа в единственном экземпляре, на которую было потрачено полгода труда.
реклама

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

Приведу пример из своего опыта. Недавно я наконец-то решил обновить файловый менеджер Total Commander, которым пользуюсь уже много лет, с устаревшей версии 7.5 до новой 9.12. За много лет работы с Total Commander я привык, что его настройки сохраняются в файл Wincmd.ini, лежащий в папке с программой. И потратив пару часов на тонкую настройку Total Commander, я был уверен, что мои настройки сохранены в Wincmd.ini в папке с программой, как и раньше.
реклама

В Total Commander можно настроить все, от шрифтов до цвета для каждого типа файлов
Однако, после переустановки Windows и запуска Total Commander, я увидел, что все настройки, за исключением «Панели инструментов», сбросились до значений по умолчанию.

реклама
Расследование причин показало, что настройки новой версии сохранились в файл Wincmd.ini, лежащий в папке C:\Users\»имя пользователя»\AppData\Roaming\GHISLER, которая была стерта при переустановке Windows. Спасло мое время и нервы в этом случае то, что перед переустановкой Windows были сохранены все папки, в которых обычно хранятся файлы пользователя и настройки программ. В этом блоге мы рассмотрим все самые основные места, откуда стоит сохранить ваши файлы и настройки, чтобы не потерять важного.
Рабочий стол

Несмотря на то, что опытные пользователи постоянно ругают новичков за использование «Рабочего стола», как места длительного хранения файлов, эту привычку не искоренить. Ведь ничего более удобного, чем «Рабочий стол» еще не придумано. Даже при написании этого блога я скачиваю иллюстрации прямо на него, и на нем же лежит папка с черновиками. Так и получается, что уже через полгода после установки Windows «Рабочий стол» уже забит не только многочисленными ярлыками и папками «Новая папка», «Новая папка (2)», но и иногда и важными документами, лежащими под рукой.

реклама
Поэтому «Рабочий стол» всегда первый кандидат на сохранение перед переустановкой Windows. Даже если визуально ничего важного на нем нет, то в одной из папок вполне может лежать что-то важное. Пригодятся нам и ярлыки игр, ведь некоторые из которых вполне спокойно переживают переустановку Windows и корректно запускаются, только создавая при этом новый профиль в документах пользователя.
Документы пользователя

Не менее важно сохранить папку «Документы», где обычно хранят свои сохранения игры, а программы — свои данные, например, мессенджер Viber держит там папку «ViberDownloads» в которой можно найти все фото и видео, которые вам присылали. Для многих игр после переустановки достаточно вернуть в папку «Документы» папку игры с сохранениями и вы можете продолжать играть с того места, с которого закончили. Но нужно учитывать, что вес папки «Документы» легко может достигать десятков гигабайт. В моем случае одна только папка сохранений игры Anno 1800 «распухла» до 8 ГБ.
Загрузки

Еще больше «распухает» папка «Загрузки», постепенно превращаясь в склад всякой всячины — от фильмов и игр, до важных рабочих документов и чеков. Держать папку «Загрузки» на системном диске из-за этого довольно непрактично и проще всего сразу перенести ее на отдельный логический, а лучше — физический диск, который не будет затрагиваться при переустановке Windows. В моем случае она перенесена в папку «E:\— Downloads —«.
Изображения и Видео

Стоит проверить и папку «Изображения», обычно становящейся хранилищем скриншотов экрана, снятых как средствами Windows, так и сторонними программами. То же самое стоит проделать с папкой «Видео», если вы сохраняете видеозаписи с экрана, например, из игр.
Application Data

Как показал мой пример с Total Commander, стоит очень внимательно отнестись к папке Application Data, лежащей по адресу c:\Users\»имя пользователя» \AppData. В ней хранят свои настройки и данные не только программы, но и некоторые игры, например, Anno 1404. Несмотря на большой размер, папку AppData лучше сохранить целиком, и удалить потом, полностью «обжившись» в новой Windows.
Браузер

С браузером в 2022 году все не просто, а очень просто. Достаточно включить синхронизацию и все ваши логины, пароли и расширения при переустановке браузера подтянутся из облака, и вы попадете в привычную рабочую среду. Но есть одно «но», которое часто забывают даже опытные пользователи. А именно — сохранить открытые вкладки в закладки, а их число при активной работе с интернетом легко переваливает за сотню. Иначе вкладки безвозвратно пропадут.

Несмотря на то, что логины и пароли будут сохранены и восстановлены, двухфакторная авторизация на сайтах сбросится и после переустановки Windows нас ждет нудный и долгий процесс получения кодов по SMS и ввода их на всех сервисах. Избежать этого можно, если вы пользуетесь браузером Mozilla Firefox, с помощью утилиты MozBackup от разработчика Pavel Cvrcek, которая полностью сохраняет ваш профиль вместе с файлами Cookies и после переустановки Windows ваш браузер будет сразу готов к работе.
Настройки программ и утилит

У каждого из нас стоит свой, специфический набор утилит, но некоторые из них требуют очень трудоемких настроек. Например, настройки вентиляторов и кривой частот напряжений в MSI Afterburner. Для MSI Afterburner настройки можно найти в расположении c:\Program Files (x86)\MSI Afterburner\Profiles, а вот для других программ их придется найти и сохранить в зависимости от того, какие программы вы используете.

Многие утилиты способны экспортировать свои настройки и это гораздо удобнее, чем искать их в папках с программами. Например, правила для фаервола simplewall или настройки оболочки для замены меню «Пуск» Classic Shell, которые я постоянно использую, можно легко экспортировать в файлы XML и восстановить за пару секунд, что гораздо быстрее, чем настраивать их заново.
Полный бэкап

Даже сохранив все вышеописанное, можно столкнуться с ситуацией, когда что-то из настроек и файлов в старой Windows утеряно навсегда. Избежать этого довольно просто, достаточно создать загрузочную флешку, содержащую утилиты для бэкапа, например, Acronis True Image, Macrium Reflect или O&O DiskImage Pro и создать полный образ системного диска. Образ потом можно будет как открыть отдельно, так и восстановить полностью.
Но главный вопрос при таком подходе — куда сохранять образ? Хорошо, если у вас есть дополнительный жесткий диск, но все чаще новые ПК обходятся без жестких дисков вообще. Выручит в таком случае быстрая флешка достаточного объема, например, Transcend Jetflash 790 из Ситилинка, объемом 256 ГБ.

Если и такого объема будет недостаточно, то стоит присмотреться к внешним жестким дискам, например, Transcend StoreJet, объемом в 1ТБ.

Итоги
Может показаться, что все действия по бэкапу файлов и сохранению настроек занимают слишком много времени, но на самом деле они заметно сэкономят его после установки Windows и чем больше у вас установлено программ, тем больше времени вы сэкономите. Заодно мы получаем два полезных бонуса, во-первых, разгребаем залежи файлов на ПК, которые за год-два использования Windows разрастаются просто до невообразимых размеров. А еще, при использовании внешних носителей, делаем бэкап важных файлов, который никогда не бывает лишним.
Пишите в комментарии, а какие настройки и файлы перед переустановкой Windows сохраняете вы?
Где хранятся файлы и программы? Программа проводник.
Одна из основных задач, с которой едва ли не ежеминутно сталкивается работающий за компьютером пользователь, — это знать где хранятся файлы и программы. Для этих целей в составе Windows предусмотрена специальная программа Проводник, которую можно запустить, выполнив последовательность команд Пуск ► Все программы ► Стандартные ► Проводник, или просто щелкнув правой клавишей мыши на кнопке Пуск и выбрав в появившемся контекстном меню пункт Проводник. Внешний вид этой программы показан на скриншоте.

Рабочее пространство программы Проводник разделено на два основных поля: в левом отображается вертикальная панель, открывающая доступ к древовидной структуре дисков, файлов и папок, в правом — содержимое выбранного диска или папки.
Чтобы просмотреть содержимое какой-либо папки или диска, достаточно щелкнуть на его изображении в левом поле — в правом появится список хранящихся в этой папке подпапок и файлов. Если, например, вы хотите перейти в папку Мои документы, просто щелкните на ее значке левой кнопкой мыши — содержимое этой папки тут же отобразится в основном окне Проводника. Щелчок на обозначении дисковода или жесткого диска, приведет вас в корневую папку выбранного диска.
Некоторые папки в окне программы Проводник отмечены символом « + » — это означает, что такая папка содержит вложенные папки. Щелчок на значке папки приводит к ее открытию: в левом окне вы сможете увидеть подпапки этой папки, а в правом — ее полное содержимое. Вы можете также перемещаться между различными объектами файловой системы, дважды щелкая мышью на обозначении этих объектов в правом окне.
Дополнительные возможности навигации по файловой системе предоставляют графические кнопки, расположенные в панели инструментов Проводника.
Кнопка Назад возвращает вас в папку, которая была открыта непосредственно перед текущей. По нажатию кнопки Вперед осуществляется обратный переход в папку, которую пользователь покинул, нажав на кнопку Назад.
Кнопка Вверх перемещает программу на один уровень вверх в файловой системе вашего компьютера.
При нажатии на кнопку Поиск прохрамма переключается в режим поиска файлов и папок. Кнопка Папки включает в левом окне программы отображение древовидной структуры файлов и папок вашего компьютера. Если кнопка не нажата, в левом окне Проводника демонстрируется информация о выбранном файле или папке, а также появляется перечень команд, которые можно выполнить с данным объектом.
Кнопка Вид позволяет изменить внешний вид отображающихся в основном рабочем окне Проводника значков, например сделать их более крупными или более мелкими.
В адресной строке этой панели вы можете набрать с клавиатуры нужный путь, нажав затем клавишу Enter или щелкнув на кнопке Переход. Другой вариант — развернув контекстное меню щелчком мыши на направленной вниз черной стрелке в правой части адресной строки, выбрать нужный диск из списка, там хранятся файлы и программы.
автобусные туры по европе