Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ответы на ЯП.docx
Скачиваний:
4
Добавлен:
01.07.2025
Размер:
661.54 Кб
Скачать

Утечки памяти и повисшие указатели

• Повисший указатель – указатель на память, которая используется для других целей. Типичный случай - память уже перераспределена. (пример – память уже перераспределена)

• К повисшему указателю приводит оператор dispose() в паскале, delete в с, с++.

• Повисшие указатели понижают безопасность программ.

• Мусор – память, которая распределена, но недоступна.

• Мусорные ссылки – ссылка на область памяти которая не используется или недоступна. (память которая распределена но недоступна)

• Говорят, что программы, которые создают мусор, дают утечки памяти.

• К утечкам памяти могут привести присваивания между указателями.

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

P и q – указатели на какие-то элементы.

P:=q приводит к тому, что p и q указывают на один и тот же элемент.

Элемент, на который ранее указывал р по-прежнему остается в памяти, но теперь он недоступен. Это утечка памяти.

Delete(p). Теперь оба указателя становятся повисшими, поскольку хранят адрес уничтоженного объекта.

◘ Способы устранения:

  1. Ручной. Присваивать указателю(параметру оператора dispose или delete) значение nil или null.

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

  3. Автоматический. Использование сборщика мусора, встроенного в некоторые языки программирования.

• Задача сборщика мусора – повторно использовать мусор, идентифицируя недоступные блоки памяти и возвращая их менеджеру динамической памяти:

•Для каждого блока ведется счетчик текущего числа указателей, ссылающихся на этот блок и автоматически освобождая блок.

•Отмечает все доступные блоки и затем собирает немаркированные блоки.

53. Концепция виртуальной памяти. Страничная организация памяти.

Виртуа́льная па́мять (англ. virtual memory) — метод управления памятью компьютера, позволяющий выполнять программы, требующие больше оперативной памяти, чем имеется в компьютере, путём автоматического перемещения частей программы между основной памятью и вторичным хранилищем (например, жёстким диском).

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

◘Применение виртуальной памяти позволяет:

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

• предоставлять программам больше памяти, чем физически установлено в системе

• в многозадачных системах изолировать выполняющиеся программы друг от друга, путём назначения им непересекающихся адресных пространств (см. защита памяти)

Страничная память — способ организации виртуальной памяти, при котором единицей отображения виртуальных адресов на физические является регион постоянного размера (т. н. страница). Типичный размер страницы — 4096 байт, для некоторых архитектур — до 128 КБ[1].

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

Управление страничным разбиением памяти обычно возлагается на специальную микросхему MMU (Memory Managment Unit - устройство управления памятью). В микропроцессоре i80486 и выше это устройство встроено в процессор.

Как и сегментация, страничная организация памяти связана с преобразованием виртуального адреса (в данном случае линейного) в физический. В страничном преобразовании базовым объектом памяти является блок фиксированного размера, называемый страницей (page). Размер страницы - 4 Кбайт.

Организация памяти в виде страниц борется с двумя проблемами:

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

Внутренней фрагментацией – блоки достаточно малого размера, поэтому (К) будет мал.

С точки зрения программиста:

Процессам виртуальное адресное пространство предоставляется непрерывным, от байта 0 до байта N;

N зависит от аппаратной поддержки (например 32бита — адрресное пространство 4Гб), делится соответственно.

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

С точки зрения менеджера памяти:

Эффективное использование памяти из-за очень низкой внутренней фрагментации.

Внешняя фрагментация полностью отсутствует и не нужно дефрагментировать.

С точки зрения защиты:

Процесс имеет доступ только к своему адресному пространству.

Допущение – все страницы виртуальной памяти всегда находятся в страницах физической памяти.

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

54. Сегментный принцип организации памяти. Сегментация памяти.

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

основная программа;

процедура;

функция;

метод;

объект;

набор локальных переменных;

набор глобальных переменных;

общий блок данных (например, COMMON-блок в языке FORTRAN);

стек;

таблица символов;

массив.

Архитектура сегментной организации памяти

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

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

base – начальный адрес сегмента в оперативной (физической) памяти;

limit – длину сегмента.

Базовый регистр таблицы сегментов - segment-table base register (STBR) содержит адрес таблицы сегментов в памяти.

Регистр длины таблицы сегментов - segment-table length register (STLR) содержит число сегментов, используемое программой.

Номер сегмента s корректен, если s < STLR.

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

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

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

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

validation-бит (аналогично страничной организации): значение бита, равное 0, означает, что сегмент неверный, т.е. не принадлежит логической памяти процесса;

полномочия чтения (read) / записи (write) / исполнения (execute) – каждое кодируется одним битом; значение бита, равное 0, означает, что процесс не имеет данных полномочий.

Например, если сегмент является сегментом данных, то система устанавливает в таблице сегментов бит защиты от исполнения равным 0. Если это сегмент кода, то целесообразна установка в 0 битов защиты от чтения и от записи.

Биты защиты связываются с сегментами. Совместный доступ к коду осуществляется на уровне сегментов.

Преимущества сегментации:

  • Сегменты не мешают друг другу.

  • Начальный адрес процедуры всегда начинается с (n,0). Что упрощает программирование.

  • Облегчает совместное использование процедур и данных.

  • Раздельная защита каждого сегмента (чтение, запись).

55. Указатели. Операции наад указателями. Типизированные и не типизированные указатели.

Указатели

Переменная, значением которой является адрес другой переменной. Объект на который указывают называется указуемым, или обозначаемым объектом. Для описания указателей используется операция косвенной адресации. & указывает, что нам нужен адрес, а не значение переменной. Указатели применяются скорее для вычисления с адресами ячеек, чем с их содержимым. Разница между переменной указателем и указуемым объектом.

Различия между указателем константой и указателем на константный указуемый объект.

Типизированные указатели не явно могут быть преобразованы в указатели на void, но не обратно.

Указатели нужны для реализации динамических структур данных, например списков, деревьев и т.д.

<Указатели>

• Это переменная, значениями которой является адрес другой переменной.

• Значение указательного типа – адрес.

• Указательная переменная(указатель) содержит адрес другой переменной или константы.

• Объект, на которой указывают, называется указуемым или обозначаемым объектом.

• Указатель ссылается на блок данных из области памяти, причем на его начало.

• Указатель может ссылаться на переменную или функцию.

• Размер (формат) адреса зависит только от величины адресного пространства компьютера и специфики его организации.

Обозначаются со *.

• Указатель - величина, предоставляющая косвенный доступ к элементам известного типа. (Типизированное средство косвенного доступа к объектам данных)

Int var =123;

Int *ptrvar;//объявление указателя

Ptrvar=&var;присвоили адрес переменной указателю

Cout<<&var;адрес переменной var

Cout<<ptrvar;адрес переменной var

Cout<<var;значение переменной 123

Cout<<*ptrvar;вывод значения содержащегося в переменной через указатель, операцией разименования указателя 123.

• Операции над указателями:

  1. Объявление *р

  2. Получение адреса р=&а

  3. Разыменование x=*p –получаем объект, на который указатель ссылается.

  4. Получение адреса указателя &p

  5. Увеличение указателя на единицу ++p

  6. Вычитание p2-p1

• Если р2 и р1 указывают на элементы типа long, то р2-р1=2, означает, что указываемые переменные разделены двумя значениями типа long, а не двумя байтами.

Int a;целое число

Int *a; указатель на целое

Int **a;указатель на указатель

Int a[10];массив

Int *a[10]; массив из десяти указателей на целые

Int (*a)[10];указатель на массив из десяти целых

Int (*a)int;указатель на функцию

Int(*a[10])int; массив из 10 указателей на функции, которые берут целый аргумент и возвращают целое

Разница между переменной-указателем и указуемым объектом

Int i1=10;

Int i2=20;

Int*ptr1=&i1;птр указывает на и1

If(ptr1>ptr2)//истина(значение адресов сравниваются)

If(*ptr1>*ptr2)//сравниваем переменные

*ptr1==*ptr2//косвенно приравниваем и1=и2=20

If(ptr1==ptr2)//ложь, указатели до сих пор разные

If(*ptr1==*ptr2)//истина, объекты равны

Ptr1=ptr2//указывают на и2, ptr1=ptr2