Чет про программирование / 19) Ручное управление памятью
.docxРучное управление памятью
В ОС работают процессы – программы. Они могут просить у ОС память с помощью системных вызовов. ОС выделяет память блоками. Процессы могут возвращать ОС блоки памяти.
В языке программирования для ручного управления памятью должны быть функции для выделения/освобождения памяти.
Память выделяется кусками, и изменить их размен нельзя. Однако можно выделить бОльший кусок (новый), скопировать в него старые данные и освободить память, занятую старым куском.
Когда процесс завершается, его память освобождается.
Выделение и освобождение памяти происходит не прямыми вызовами. Программисту нужна память разного размера, а ОС выдает равные блоки. Эти проблемы помогает решить менеджер памяти, который реализован в виде специальных функций в языке программирования с поддержкой ручного управления памятью.
Куча – область памяти, выделенная процессу. Менеджер памяти пытается найти в куче свободный фрагмент и, если не находит, просит у ОС новый блок. При освобождении памяти менеджер помечает эти куски.
Проблемы ручного управления памятью
-
Утечка памяти - процесс неконтролируемого уменьшения объёма свободной оперативной или виртуальной памяти компьютера, связанный с ошибками в работающих программах, вовремя не освобождающих не нужные уже участки памяти (забываем освободить ненужную память).
-
Висящие ссылки (указатели) - это оставшаяся в использовании ссылка на объект, который уже удалён. После удаления объекта все сохранившиеся в программе ссылки на него становятся «висячими». Память, занимаемая ранее объектом, может быть передана операционной системе и стать недоступной, или быть использована для размещения нового объекта в той же программе. В первом случае попытка обратиться по «повисшей» ссылке приведёт к срабатыванию механизма защиты памяти и аварийной остановке программы, а во втором — к непредсказуемым последствиям.
Операторы ЯП Паскаль для ручного управления памятью
-
New(<var p: типизированный_pointer>); - выделяет память в соответствии с размером типизированного указателя. После вызова в переменой p находится указатель на начало. Если выделить память не удалось, то p = nil.
-
Dispose(<var p: pointer>); - освобождает память по указателю. Сразу после выполнения p становится висячей ссылкой.
Другие способы работы с памятью в ЯП Паскаль:
-
Getmem(Var P : Pointer; Size : Word)- выделить указанное количество памяти.
-
Freemem(Var P : Pointer; Size : Word) – освободить память.
Смешивать использование разных способов не стоит, поскольку менеджер памяти не рассчитывает на это.