Страница 42 из 60
Фрагментация Когда блоки доступной памяти располагаются между участками распределенной памяти, то говорят, что происходит фрагментация памяти. Хотя свободной памяти как правило бывает достаточно, что- бы удовлетворить запрос памяти, однако трудность заключается в том, что размеры отдельных участков свободной памяти недостаточны для этого, несмотря на то, что при их объединении получится дос- таточный объем памяти. На рис.18 показано, как при определенной последовательности обращения к процедурам "New" и "Dispose" может возникнуть такая ситуация. Когда блоки доступной памяти располагаются между участками распределенной памяти, то говорят, что происходит фрагментация памяти. Хотя свободной памяти как правило бывает достаточно, что- бы удовлетворить запрос памяти, однако трудность заключается в том, что размеры отдельных участков свободной памяти недостаточны для этого, несмотря на то, что при их объединении получится дос- таточный объем памяти. На рис.18 показано, как при определенной последовательности обращения к процедурам "New" и "Dispose" может возникнуть такая ситуация.
A,B,C,D:^integer W,X,Y,Z:^real;
-----T------------------------------------¬ new(A) ¦ A ¦ ¦ L----+------------------------------------- -----T-------T----------------------------¬ new(W) ¦ A ¦ W ¦ ¦ L----+-------+----------------------------- -----T-------T----T-----------------------¬ new(B) ¦ A ¦ W ¦ B ¦ ¦ L----+-------+----+------------------------ -----T-------T----T----T------------------¬ new(C) ¦ A ¦ W ¦ B ¦ C ¦ ¦ L----+-------+----+----+------------------- -----T-------T----T----T-------T----------¬ new(X) ¦ A ¦ W ¦ B ¦ C ¦ X ¦ ¦ L----+-------+----+----+-------+----------- -----T-------T----T----T-------T------T---¬ new(Y) ¦ A ¦ W ¦ B ¦ C ¦ X ¦ Y ¦ ¦ L----+-------+----+----+-------+------+---- -----T-------T----T----T-------T------T---¬ dispose(B)¦ A ¦ W ¦ ¦ C ¦ X ¦ Y ¦ ¦ L----+-------+----+----+-------+------+---- new(Z) Запрос не может быть удовлетворен, поскольку
нет участка непрерывной свободной памяти доста- точного размера
В некоторых случаях фрагментация уменьшается, так как функ- ции динамического распределения памяти объединяют соседние участ- ки памяти. Например, пусть были выделены участки памяти A,B,C,и D /см. ниже/. Затем освобождаются участки B и C. Эти участки можно объединить, поскольку они располагаются рядом. Однако, если осво- бождаются участки B и D, то объединить их нельзя будет, поскольку между ними находится участок C который еще не освобожден: ________________________ ¦ ¦ ¦ ¦ ¦ ¦ A ¦ B ¦ C ¦ D ¦ ¦_____¦_____¦_____¦_____¦
Так как B и D освобождены, а C занят, то может возникнуть вопрос: "Почему бы Турбо Паскалю не переслать содержимое C в D и затем объединить B и C?" Трудность заключается в том, что ваша программа не будет "знать", что это пересылка произошла. Один из способов предотвращения большой фрагментации заклю- чается в том, чтобы всегда выделять одинаковые участки памяти. В этом случае все освобожденные участки могут использоваться при любых последующих запросах на выделение памяти и таким образом будет использована вся свободная память. Если нельзя использовать всегда одинаковый размер выделяемых участков, то следует ограни- читься только несколькими размерами. Иногда этого можно достиг- нуть путем объединения нескольких запросов на выделение небольших участков в один запрос на выделение одного большого участка памя- ти. Не следует для предотвращения фрагментации выделять больше памяти, чем действительно требуется, поскольку получаемая выгода не окупит потерь от неиспользованной памяти. Можно использовать другой подход к решению этой проблемы: при работе программы можно записывать информацию во временный дисковый файл, освободить всю память и затем считать информацию с диска в память. При считыва- нии информации не будет создаваться никаких промежутков.
|