Что такое фрагментация оперативной памяти

Обновлено: 06.07.2024

Презентацию к данной лекции Вы можете скачать здесь.

Введение

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

Откачка и подкачка

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

Откачка и подкачка (swapping) – это действия операционной системы по откачке (записи) образа неактивного процесса на диск или подкачке (считыванию) активного процесса в основную память . Необходимость выполнения подобных действий вызвана нехваткой основной памяти.

Файл откачки (backing store) - область дисковой памяти, используемая операционной системой для хранения образов откачанных процессов. Файл откачки организуется максимально эффективно: обеспечивается прямой доступ ко всем образам процессов в памяти (например, через таблицу по номеру процесса).

Популярная разновидность стратегии откачки и подкачки – roll out / roll in: откачка и подкачка на базе приоритетов; более приоритетные процессы исполняются, менее приоритетные – откачиваются на диск .

Наибольшие временные затраты на откачку – это затраты на передачу данных: полный образ процесса может занимать большую область памяти. Общее время откачки пропорционально размеру откачиваемых данных.

В распространенных ОС – UNIX , Linux, Windows и др. – реализованы различные стратегии откачки и подкачки.

Схема откачки и подкачки изображена на рис. 16.1.

Схема откачки и подкачки.

Смежное распределение памяти

Наиболее простая и распространенная стратегия распределения памяти – смежное распределение памяти – распределение памяти для пользовательских процессов в одной смежной области памяти. Основная память разбивается на две смежных части ( partitions ), которые "растут" навстречу друг другу: резидентная часть ОС и вектор прерываний – по меньшим адресам. Для пользовательских процессов память распределяется в одном и том же смежном участке памяти. Для каждого процесса регистр перемещения указывает на начало выделенной ему области памяти, регистр границы содержит длину диапазона логических адресов . Каждый логический адрес должен быть меньше содержимого регистра границы. Физический адрес вычисляется аппаратно как сумма логического адреса и значения регистра перемещения. Схема адресации с аппаратной поддержкой регистров перемещения и границы изображена на рис. 16.2.

Адресация с аппаратной поддержкой регистров перемещения и границы.


увеличить изображение
Рис. 16.2. Адресация с аппаратной поддержкой регистров перемещения и границы.

Общая задача распределения памяти и стратегии ее решения

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

Возникает общая задача распределения памяти: Имеется список свободных областей памяти и список занятых областей разного размера. Разработать и реализовать оптимальный ( по некоторому критерию) алгоритм выделения свободного смежного участка памяти длины n (слов или байтов).

Для решения данной задачи применяются следующие стратегии: метод первого подходящего (first-fit), метод наиболее подходящего (best-fit) и метод наименее подходящего (worst-fit).Рассмотрим каждую из них подробнее.

Метод первого подходящего:Выбирается первый по списку свободный участок подходящего размера (не меньшего, чем n ). На первый взгляд, данная стратегия оптимальна, но далее мы увидим, что это не всегда так.

Метод наиболее подходящего:Выбирается из списка наиболее подходящий свободный участок (минимального размера, не меньшего, чем n ). В отличие от предыдущего метода, требует просмотра всего списка, если список не упорядочен по размеру областей. Применение метода приводит к образованию оставшейся части самого маленького размера.

Метод наименее подходящего: Выбирается из списка подходящая область наибольшего размера. Почему наибольшего? Чтобы избежать фрагментации (проблема фрагментации подробно рассмотрена далее в данной лекции).

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

Фрагментация

Фрагментация – это дробление памяти на мелкие не смежные свободные области маленького размера. Фрагментация возникает после выполнения системой большого числа запросов на память , таких, что размеры подходящих свободных участков памяти оказываются немного больше, чем требуемые. Например, если имеется 100 смежных свободных областей памяти по 1000 слов, то после выполнения 100 запросов на память по 999 слов каждый в списке свободной памяти останутся 1000 областей по одному слову.

Фрагментация бывает внутренняя и внешняя. При внешней фрагментации имеется достаточно большая область свободной памяти, но она не является непрерывной. Внутренняя фрагментация может возникнуть вследствие применения системой специфической стратегии выделения памяти, при которой фактически в ответ на запрос память выделяется несколько большего размера, чем требуется, - например, с точностью до страницы (листа ), размер которого – степень двойки. Страничная организация памяти подробно рассматривается далее в данной лекции.

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

При компактировке памяти и анализе свободных областей может быть выявлена проблема зависшей задачи: какая-либо задача может "застрять" в памяти, так как выполняет ввод-вывод в свою область памяти ( по этой причине откачать ее невозможно). Решение данной проблемы: ввод-вывод должен выполняться только в специальные буфера, выделяемой для этой цели операционной системой.


Оказывается, я не одинок в этой проблеме. Приложения Ruby могут использовать много памяти. Но почему? Согласно Heroku и Нейту Беркопеку, в основном раздутие связано с фрагментацией памяти и чрезмерным распределением по кучам.

Беркопек пришёл к выводу, что существует два решения:

  1. Либо используйте совершенно другой распределитель памяти, чем в glibc — обычно jemalloc, либо:
  2. Установите магическую переменную среды MALLOC_ARENA_MAX=2 .

Магия — это просто наука, которую мы пока не понимаем. Поэтому я отправился в исследовательское путешествие, чтобы узнать всю правду. В этой статье осветим следующие темы:

  1. Как работает распределение памяти.
  2. Что это за «фрагментация» и «чрезмерное распределение» памяти, о которых все говорят?
  3. Что вызывает большое потребление памяти? Ситуация соответствует тому, что говорят люди, или есть что-то ещё? (спойлер: да, есть кое-что ещё).
  4. Существуют ли альтернативные решения? (спойлер: я нашёл одно).

Распределение памяти в Ruby происходит на трёх уровнях, сверху вниз:

  1. Интерпретатор Ruby, который управляет объектами Ruby.
  2. Библиотека распределителя памяти операционной системы.
  3. Ядро.

На своей стороне Ruby организует объекты в областях памяти, называемых страницами кучи Ruby. Такая страница кучи разбита на слоты одинакового размера, где один объект занимает один слот. Будь то строка, хеш-таблица, массив, класс или что-то ещё, он занимает один слот.


Слоты на странице кучи могут быть заняты или свободны. Когда Ruby выделяет новый объект, тот сразу пытается занять свободный слот. Если свободных слотов нет, то будет выделена новая страница кучи.

Слот небольшой, около 40 байт. Очевидно, что некоторые объекты в него не поместятся, например, строки по 1 МБ. Тогда Ruby сохраняет информацию в другом месте за пределами страницы кучи, а в слот помещает указатель на эту внешнюю область памяти.


Данные, которые не помещаются в слот, хранятся вне страницы кучи. Ruby помещает в слот указатель на эти внешние данные

Как страницы кучи Ruby, так и любые внешние области памяти выделяются с помощью распределителя памяти системы.

Системный распределитель памяти

Распределитель памяти операционной системы является частью glibc (среда выполнения C). Он используется почти всеми приложениями, а не только Ruby. У него простой API:

  • Память выделяется вызовом malloc(size) . Вы передаёте ему количество байт, которое хотите выделить, а он возвращает либо адрес выделения, либо ошибку.
  • Выделенная память освобождается вызовом free(address) .

В свою очередь, распределитель памяти обращается к API ядра. Он забирает из ядра гораздо большие куски памяти, чем запрашивают его собственные абоненты, поскольку вызов ядра дорогостоящий и у API ядра есть ограничение: оно может выделять память только кратно 4 КБ.


Распределитель памяти выделяет большие куски — они называются системные кучи — и делит их содержимое для удовлетворения запросов из приложений

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

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


Ruby выделяет память из распределителя памяти, который, в свою очередь, выделяет её из ядра

Ядро может выделять память только юнитами по 4 КБ. Один такой блок 4 КБ называется страницей. Чтобы не путать со страницами кучи Ruby, для ясности будем использовать термин системная страница (OS page).

Причину сложно объяснить, но так работают все современные ядра.

Выделение памяти через ядро оказывает значительное влияние на производительность, поэтому распределители памяти пытаются минимизировать количество вызовов ядра.

Определение использования памяти

Таким образом, память выделяется на нескольких уровнях, и каждый уровень выделяет больше памяти, чем ему действительно нужно. На страницах кучи Ruby могут быть свободные слоты, как и в системных кучах. Поэтому ответ на вопрос «Сколько памяти используется?» полностью зависит от того, на каком уровне вы спрашиваете!

Инструменты вроде top или ps показывают использование памяти с точки зрения ядра. Это означает, что верхние уровни должны согласованно работать, чтобы освободить память с точки зрения ядра. Как вы узнаете далее, это сложнее, чем кажется.

Фрагментация памяти означает, что выделения памяти беспорядочно разбросаны. Это может вызвать интересные проблемы.

Фрагментация на уровне Ruby

Рассмотрим сборку мусора Ruby. Сборка мусора для объекта означает маркировку слота страницы кучи Ruby как свободного, что позволяет его повторно использовать. Если вся страница кучи Ruby состоит только из свободных слотов, то всю её целиком можно освободить обратно в распределитель памяти (и, возможно, обратно в ядро).


Но что произойдёт, если свободны не все слоты? Что делать, если у нас много страниц кучи Ruby, а сборщик мусора освобождает объекты в разных местах, так что в конечном итоге остаётся много свободных слотов, но на разных страницах? В такой ситуации у Ruby есть свободные слоты для размещения объектов, но распределитель памяти и ядро продолжат выделять память!

Фрагментация на уровне распределителя памяти

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


Подумайте, что произойдёт, если у нас есть выделение на 3 КБ, а также выделение на 2 КБ, разбитое на две системные страницы. Если вы освободите первые 3 КБ, обе системные страницы останутся частично заняты и не могут быть освобождены.


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

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

Вполне вероятно, что фрагментация является причиной чрезмерного использования памяти в Ruby. Если так, то какая из двух фрагментаций наносит больший вред? Это…

  1. Фрагментация страниц кучи Ruby? Или
  2. Фрагментация распределителя памяти?


ObjectSpace.memsize_of_all возвращает память, занятую всеми активными объектами Ruby. То есть всё место в своих слотах и любые внешние данные. На приведённой выше диаграмме это размер всех синих и оранжевых объектов.

GC.stat позволяет узнать размер всех свободных слотов, т. е. всю серую область на иллюстрации выше. Вот алгоритм:


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

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


это… просто… безумие!

Результат показывает, что Ruby настолько слабо влияет на общий объём используемой памяти, что не имеет значения, фрагментированы страницы кучи Ruby или нет.

Придётся искать виновника в другом месте. По крайней мере, теперь мы знаем, что Ruby не виновата.

Ещё один вероятный подозреваемый — распределитель памяти. В конце концов, Нейт Беркопек и Heroku заметили, что возня с распределителем памяти (либо полная замена на jemalloc, либо установка магической переменной среды MALLOC_ARENA_MAX=2 ) резко снижает использование памяти.

Давайте сначала посмотрим, что делает MALLOC_ARENA_MAX=2 и почему это помогает. Затем исследуем фрагментацию на уровне распределителя.

Чрезмерное распределение памяти и glibc

Причина, почему помогает MALLOC_ARENA_MAX=2 , связана с многопоточностью. Когда несколько потоков одновременно пытаются выделить память из одной и той же системной кучи, они борются за доступ. Только один поток за раз может получить память, что снижает производительность многопоточного распределения памяти.


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

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

Фактически, максимальное количество системных куч, выделенных таким образом, по умолчанию равно количеству виртуальных процессоров, умноженному на 8. То есть в двухъядерной системе с двумя гиперпотоками на каждом получается 2 * 2 * 8 = 32 системные кучи! Это то, что я называю чрезмерным распределением.

Почему множитель по умолчанию такой большой? Потому что ведущий разработчик распределителя памяти — Red Hat. Их клиенты — большие компании с мощными серверами и тонной оперативной памяти. Вышеуказанная оптимизация позволяет повысить среднюю производительность многопоточности на 10% за счёт значительного увеличения использования памяти. Для клиентов Red Hat это хороший компромисс. Для большинства остальных — вряд ли.

Нейт в своём блоге и статья Heroku утверждают, что увеличение числа системных куч увеличивает фрагментацию, и ссылаются на официальную документацию. Переменная MALLOC_ARENA_MAX уменьшает максимальное количество системных куч, выделяемых для многопоточности. По такой логике, она уменьшает фрагментацию.

Визуализация системных куч

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

К сожалению, не существует инструментов для визуализации системных куч, поэтому я сам написал такой визуализатор.

Во-первых, нужно как-то сохранить схему распределения системных куч. Я изучил исходники распределителя памяти и посмотрел, как он внутренне представляет память. Далее написал библиотеку, которая перебирает эти структуры данных и записывает схему в файл. Наконец, написал инструмент, который берёт такой файл в качестве входных данных и компилирует визуализацию в виде изображений HTML и PNG (исходный код).


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

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

Хотя фрагментация остаётся проблемой, но дело не в ней!

Скорее, проблема в большом количестве серого цвета: это распределитель памяти не отдаёт память обратно в ядро!

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

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

Я знал об этой функции, но не думал, что она полезна, потому что в руководстве сказано следующее:

Функция malloc_trim() пытается освободить свободную память в верхней части кучи.

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

Что произойдёт, если вызывать эту функцию во время сборки мусора? Я изменил исходный код Ruby 2.6, чтобы вызывать malloc_trim() в функции gc_start из gc.c, например:


И вот результаты теста:


Какая большая разница! Простой патч уменьшил потребление памяти почти до уровня MALLOC_ARENA_MAX=2 .

Вот как всё выглядит в визуализации:


Мы видим много белых областей, которые соответствуют системным страницам, освобождённым обратно в ядро.

Оказалось, что фрагментация, в основном, ни при чём. Дефрагментация по-прежнему полезна, но основная проблема заключается в том, что распределитель памяти не любит освобождать память обратно в ядро.

К счастью, решение оказалось очень простым. Главное было найти первопричину.

Исходный код визуализатора

Что насчёт производительности?

Производительность оставалась одним из главных опасений. Вызов malloc_trim() не может обходиться бесплатно, а по коду алгоритм работает в линейном времени. Поэтому я обратился к Ною Гиббсу, который запустил бенчмарк Rails Ruby Bench. К моему удивлению, патч вызвал небольшое увеличение производительности.

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

Как работает оперативная память с Windows?

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

Что происходит с оперативной памятью?

Memory allocation for bytes failed

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

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

Так что же?

Как работает дефрагментация оперативной памяти ?

Обычно дефрагментация оперативной памяти основана на двух принципах:

Оба трюка освобождают оперативную память. Но что происходит на самом деле: теперь уже запущенным программам приходится черпать память не из RAM, а с виртуальной части. То есть с винчестера. В итоге ситуация патовая: память для нового приложения освобождена, а остальные службы и программы тормозят. И в чём тогда смысл?

При всех полезных функциях дефрагментация оперативной памяти в любом случае на современном компьютере с более чем 1 Гб установленной оперативной памяти и при работающих программах, используемых 99,99999 процентами пользователей, абсолютно бессмысленна. Советую вам поискать другие утилиты по оптимизации работы вашей системы в другом русле.

Хотите оптимизировать память вручную? Просто закрывайте программы, котрые не нужны. К чему перегружать компьютер с небольшим объёмом физической памяти? Самый действенный способ описан в статье Самостоятельный апгрейд компьютера. Как добавить оперативную память. И не стоит верить в чудеса.

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

Появление или непоявление фрагментации зависит от метода организации памяти.

Внутренняя фрагментация – при заполнении страниц в среднем половина последней страницы остаётся незаполненной. Эти «дыры» и есть внутренняя фрагментация.

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

При страничной организации памяти внешняя фрагментация отсутствует, а потери из-за внутренней фрагментации, поскольку процесс занимает целое число страниц, ограничены частью последней страницы процесса.

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

Одним из методов борьбы с фрагментацией является перемещение всех занятых участков в сторону старших либо в сторону младших адресов, так, чтобы вся свободная память образовывала единую свободную область. В дополнение к функциям, которые выполняет ОС при распределении памяти переменными разделами, в данном случае она должна еще время от времени копировать содержимое разделов из одного места памяти в другое, корректируя таблицы свободных и занятых областей. Эта процедура называется сжатием или дефрагментацией. Сжатие может выполняться либо при каждом завершении задачи, либо только тогда, когда для вновь поступившей задачи нет свободного раздела достаточного размера. В первом случае требуется меньше вычислительной работы при корректировке таблиц, а во втором - реже выполняется процедура сжатия. Так как программы перемещаются по оперативной памяти в ходе своего выполнения, то преобразование адресов из виртуальной формы в физическую должно выполняться динамическим способом.

Вернее более конкретный вопрос. Как она рассчитывается?
Допустим фрагментация 10% объем 1Гб. 500 мег занято.
Каков максимальный гарантированный размер куска свободной памяти?


Ну, если минимальный выделяемый кусок - это 8 байт, то максимальный гарантированный. 0 байт!

А как ты рассчитываешь процент фрагментации? :)

Я и не рассчитываю - утилита показывает, а я хочу узнать что она ввиду имеет.


есть 2 вида фрагментации: внутренняя и внешняя. внутренняя фрагментация суть сумма _неиспользуемых_ областей памяти _во_всех_ выделенных кусках памяти. внешняя фрагментация суть сумма всех кусков continious памяти < MIN_ALLOC_SIZE.


> утилита показывает

Хммм. что за утилита?

>Хммм. что за утилита? cat /proc/buddyinfo ? :)

>Хммм. что за утилита?
cat /proc/buddyinfo ? :)
PS: сори, протупил с разметкой..

> Что такое фрагментация памяти

это просто научное название состояния сознания с тяжелого бодуна. Когда события предыдущего вечера помнятся несвязными урывками и изобилуют пробелами.

А че в нынешних университетах курс системного и прикладного ПО уже не проходят, на котором все это рассказываетсяя?

у нас на 2 курсе сейчас как раз идет, правда я в универ почти не хожу =)

Так сходи и расскажи, что говорят! А то будешь потом как я по форумам мотаться!:)

ну если научно популярно тебя устроит, то так:

используется странично - сегментная адресация. сегменты могут быть произвольного размера,

допустим было 3 сегмента:

удалили сегБ 2 кб и загрузили сегД 3 кб

вот это и сесть фрагментация пмяти, естественно она зависит от используемой модели и процессора-сегментная. страничная, сегментно-страничная и etc

Это не откровение и не сакральные знания. Хотелось бы знать как ее считают, а не что она такое. Что она такое и так знаю.


> Хотелось бы знать как ее считают, а не что она такое

У тебя же есть утилита, которая ее считает - посмотри исходники.



>Это не откровение и не сакральные знания. Хотелось бы знать как ее считают, а не что она такое. Что она такое и так знаю.

ч0рт, а ч думал я самый умный =)

Читайте также: