Лекция 06 - chrislvt/OS GitHub Wiki
кусочек пятой лекции в тему:
Можно ли выполнять программу, которая не находится в памяти целиком? - Да, можно Что должно находиться в памяти? - Части кода, к которым в данный момент обращается процессор. Эта идея воплотилась в понятии виртуальная память.
Виртуальная память - кажущаяся, но реально не существующая. Виртуальная память - это защищенное адресное пространство.
Три схемы управления виртуальной памятью:
- Страницами по запросу
- Сегментами по запросу
- Сегментами, поделёнными на страницы, по запросу
"По запросу" значит, что соответствующие части кода загружаются в память, когда процессор обращается к этим частям кода. В памяти эти части отсутствуют -> возникнет исключение (page fault) - в результате исключения отсутствующая в памяти страница будет в нее загружена.
Управление памятью страницами по запросу.
Программа "как бы" находится в виртуальном адресном пространстве. Размер виртуального адресного пространства - 4Гб. Команды и данные (к которым в данный момент обращается процессор) должны находиться на страницах, которые загружены в память. Каждому процессу система выделяет виртуальное адресное пространство. Виртуальные адреса преобразуются в физические.
3 способа преобразования виртуального адреса к физическому.
- Прямое отображение
- Ассоциативное отображение
- Ассоциативно-прямое отображение
Было оговорено, что программа может выполняться даже если она загружена в память не полностью, это основная идея виртуальной памяти, но в памяти должны находиться те части кода, с которыми в конкретный момент времени работает процессор. Это означает, что в памяти должны находиться команды и ДАННЫЕ, к которым в текущий момент времени обращается процессор. Понятно, что эти команды и данные должны находиться на страницах, которые загружены в память, тогда такую программу процессор может выполнять. Существует 3 способа преобразования виртуального адреса в физический. Речь уже идёт о виртуальных адресах. Это означает, что каждому процессу система выделяет виртуальное адресное пространство. Соответственно в физические преобразуются виртуальные адреса. Такое виртуальное адресное пространство можно себе представить следующим образом (тут вроде чё-то рисует и параллельно говорит следующее предложение). (03:10) Это какой-то (аддон? не понятно что за слово), определяемое особенностью системой объём адресов. Например, в 32-х разрядных системах это 4ГБ и эти 4ГБ в разных системах могут разделяться по-разному, но в общем-то это защищенное адресное пространство
Защищенное адресное пространство.
(04:10)Имеется в виду это адресное пространство программы и made-in (??? нихуя не понял чё она сказала...) систем (отображение системы). Старые учебники не оперируют такими понятиями, это уже представление о виртуальном адресном пространстве, которое даёт конкретная ОС, такие как семейство Windows и Linux`ы. Итак, 3 схемы или способа преобразования виртуального адреса к физическому:
Прямое отображение
IP??????? картинка с лекции
Виртуальный адрес делится на 2 части. В процессоре должен находиться регистр начального адреса таблицы страниц. Таблица страниц находится в оперативной памяти.
Часть виртуального адреса, которая называется номер страницы (страница) - смещение к дескриптору страницы в таблице страниц.
Если страница загружена в физическую память, то у этой страницы должен быть физический адрес. К адресу физической страницы добавляется смещение, в результате этого преобразования получаем линейный физический адрес (адрес конкретного байта физической памяти).
В дескрипторе страницы также содержится набор флагов, который позволяет работать с этой страницы. Если страницы виртуального адресного пространства и физической памяти одинаковые, то смещение в этих страницах будет одно и то же.
Таблица страниц находится в оперативной памяти, то есть для того, чтобы сформировать физический адрес команды/данных, надо обратиться к этой таблице в оперативной памяти. Обращение к памяти - крайне затратная операция. Поэтому был предложен способ ассоциативного отображения.
1 способ называется в классическом представлении "прямое отображение". Виртуальный адрес делится на 2 части. В процессоре должен находиться регистр начального адреса таблицы страниц (Усиленно продолжает рисовать). Таблица страниц находится в оперативной памяти, соответственно в регистре процессора находится начальный адрес этой таблицы. Часть виртуального адреса называется номер страницы (страница) - это смещение к дескриптору страницы в таблице страниц, если страница загружена в физическую память, то у этой страницы должен быть физический адрес. Очевидно, что в дескрипторе страницы должны быть также флаги (набор флагов), который позволяет работать с этой страницей. Очевидно, что если у нас страницы виртуального адресного пространства и физ. памяти одинаковые, то смещение в этих страницах будет одно и то же, значит к полученному адресу физической страницы добавляется смещение и мы получаем в результате этого преобразования линейный физ. адрес. Ну, в наших системах это адрес байта физической памяти. На семинарах мы с вами говорили, что такие преобразования, когда таблицы, из которых надо получать начальный адрес будь то сегмента или страницы находятся в оперативной памяти, то мы прежде чем сформировать адрес команды, данных должны обратиться к этой таблице в ОП, то есть мы тратим на это циклы памяти, что является крайне затратным. Здесь рассуждения такие: коль скоро таблица находится в ОП, значит постоянно надо обращаться к этой таблице в ОП, чтобы сформировать физ. адрес, что приводить к затратам. Очевидно, что уже в 70-е годы прошлого века, когда была сформулирована идея виртуальной памяти - стало понятно, что это крайне затратное действие, тогда был предложен следующий способ.
Ассоциативное отображение (или ассоциативное преобразование)
Процессор работает с оперативной памятью через соответствующую шину (аппаратное соединение): необходимо указать адрес, выставить его на шину, указать направление передачи данных и считать данные (команда read). Ассоциативное отображение предполагает использование специального вида памяти - ассоциативной памяти.
2 вида ассоциативной памяти:
- параллельная
- последовательная
В параллельной ассоциативной памяти выборка данных осуществляется за 1 такт за счет одновременного сравнения так называемого ключа со всеми полями, позволяющими осуществлять такую выборку. В данном случае так называемый ключ - это номер страницы.
Виртуальный адрес поделен на 2 части.
Ассоциативная память - очень дорогая память. Это регистровая память. К тому же, в этой памяти число элементов удваивается из-за необходимости выполнения сравнения.
Схема совпадения.
Если совпадение происходит по всем разрядам, то формируется разрешающий импульс и происходит считывание за один такт.
Понятно, что с оперативной памятью процессор работает через соответствующую шину, т.е. через соответствующее АППАРАТНОЕ СОЕДИНЕНИЕ, очевидно, что организация оперативной памяти предполагает обязательное действие, т.е. необходимо указать адрес, выставить его на шину, указать направление передачи данных и считать данные (команда READ). Схемотехника развивалась бурно и интенсивно, Ассоциативное отображение предполагает использование специального вида памяти, а именно АССОЦИАТИВНОЙ ПАМЯТИ, которая бывает 2х видов: параллельная и последовательная (мы рассматриваем параллельную). В параллельной ассоц. памяти выборка данных осуществляется за 1 такт за счёт одновременного сравнения "ключа" со всеми полями, позволяющими осуществлять такую выборку. Схема представляет из себя виртуал. адрес, который поделён на 2 части и ассоциативная память. (Рисунок) Вот таким образом демонстрируется, что сравнение выполняется параллельно. на примере 4-х разрядов будет показано (далее снова рисунок)... Ассоциативная память - это очень дорогая память и всегда подчёркивается, что это регистровая память, к тому же и в этой памяти число элементов удваивается из-за необходимости выполнения сравнения (рисует...). Если совпадение происходит по всем разрядам - формулируется разрешающий импульс и происходит считывание за один такт. Картинка наглядно иллюстрирует почему память "дорогая". Поэтому в чистом виде ассоциативное отображение не используется.
Мир прогрессирует => увеличивается размер адресного пространства процесса => увеличивается размер таблицы страниц
Ассоциативно-прямое отображение
Ассоциативно-прямое отображение предполагает комбинацию первых двух методов. Существует и таблица страниц и так называемый ассоциативный кэш.
Вот он base address из регистра процессора. Соответственно p(п) это смещение. В итоге мы получаем адрес физической страницы и добавляем смещение. Сначала физический адрес страницы ищется в ассоциативном кэше, если в кэше страница не найдена, то она ищется в таблице страниц. При этом очевидно ОЧЕНЬ ВАЖНО для успешной реализации такой схемы определенные соображения по работе с этим кэшем. Были проведены многочисленные исследования какой-то(не могу разобрать 26:50 первая часть) модели (мы вернемся в ним сегодня но позже). Программы наши обладают свойством локальности. Это означает что если обращение было к какой-то странице то следующие обращения (очень вероятно) будут к этой же странице. Здесь приходится забегать вперед. В те годы это было эвристическое правило, которое потом было подтверждено большим количеством исследований. Это свойство локальности, в те времена особенно, следовало из самих программ. У нас архитектура Фон Неймана и у нас программы в памяти располагаются в последовательных адресах. При этом оказалось, что наиболее часто в программах выполняется именно следование( действия выполняются одно за другим). Это свойство самого человека. Человек сугубо последовательное существо. У нас с вами один процессор, одна голова, две руки. Мы можем делать все строго последовательно. Вся техника слепок с человека, с его возможностей. Вычислительная техника является только еще одним подтверждением этого. В общем действия выполняемые последовательно встречаются в наших программах чаще чем ветвление. Соответственно данные в памяти так же у нас хранятся в последовательных адресах. Строки - массивы символов, они также хранятся в последовательных адресах. Массивы хранятся по младшему индексу в последовательных адресах. Даже современное программирование не смогло резко изменить ситуацию, несмотря на то, что программирование очень поменялось в сторону использования каких-то функций(не могу разобрать 30:38 первая часть), в сторону других идей, которые стали важнейшими. Не смотря на это наши программы обладают свойством локальности. Повторяет этот кусок: “Программы наши обладают свойством локальности. Это означает что если обращение было к какой-то странице то следующие обращения(очень вероятно) будут к этой же странице”. То есть если в ассоциативной памяти хранить адреса физических страниц к которым были последние обращения, то такой кэш будет работать крайне эффективно. И даже небольшой по объему кэш позволяет получить скоростные характеристики равные примерно 90% полностью ассоциативной памяти. В современных процессорах(Intel) используется именно такая схема ассоциативно-прямого отображения. Название кэш-TLB (translation lookaside buffer) не принадлежит фирме Intel, это название возникло значительно раньше. Фирма Intel предложила собственное схемотехническое решение(это их достижение(на семинарах подробнее про кэши)).
Двухуровневая страничная организация.
Объем программного кода быстро рос. Соответственно (не слышу слово 34:26 первая часть) объема программного кода растут размеры таблиц страниц. Таблицы страниц являются системными таблицами, они должны находится в системной области памяти(то есть в области данных ядра системы). Сама оперативная память является дефицитным ресурсом. Область данных ядра системы НАИдефицитнеший ресурс(еще более дефицитный). Но рост программного кода приводит к интересным вещам. Какие-то части программы в определенных прогонах могут вообще не работать. То есть понятно, что программы(это же не в тупую увеличения адресного пространства программы) это другая организация программ в частности библиотеки(в настоящее время динамически-подгружаемые библиотеки). Программирование меняется, объемы кода меняются, но в то же время меняется и организация этого кода, важнейшим моментом является то, что в разных прогонах могут использоваться разные части кода(какие-то части могут вообще не использоваться). Все адресное пространство программы описывается соответствующей таблице страниц. В данном случае вы видите, что у нас одна таблица страниц на всё адресное пространство. То есть эта огромная таблица страниц должна находится в оперативной памяти, загромождая её(загромождая системную область памяти), поэтому в IBM 360/67, IBM 370 была организована Двухуровневая страничная организация, было введено понятие гипер страницы. То есть адресное пространство процесса делится на гипер страницы, а гипер страницы на страницы. Само название гипер страницы указывает, что это гипер страница кратная размеру страницы. В результате виртуальный адрес делится на три части:
(бубнит это : Это все равно регистр начального адреса таблицы гипер страниц.) В такой организации у нас будет столько страниц таблиц сколько у нас гипер страниц. (опять что-то рисует) В дескрипторе гипер страницы находится начальный адрес таблицы страниц. Очевидно что и в этой схеме эффективно использовать ассоциативную память, но доступ к ассоциативной памяти осуществляется по двум полям. Если мы не нашли страницу в ассоциативном кэше, то для для того чтобы получить физический адрес надо выполнить два обращения к оперативной памяти(к таблице гипер страниц и к таблице страниц), то есть затраты. Выигрыш в том, что в памяти могут находится только актуальные таблицы страниц, то есть те таблицы страниц в которых находятся страницы с которыми в данный момент работает процессор. Мы видим колоссальные затраты на страничное преобразование(в процессорах интел-32разрядных это называется “базовая схема преобразования” только НЕ ОНИ ПРИДУМАЛИ этот подход. Этот подход был предложен в 70 годы прошлого века. Во время интенсивного развития вычислительных систем, операционных систем.).
Такая (гибкая?) схема, которая позволяет держать в памяти только актуальные таблицы страниц, но необходимо рассмотреть другую проблему. А что делать, если все страницы физической памяти распределены? Говорит, что посылает картинку(из какой-то книжки, вроде собственность IBM) с так называемым снимком памяти Снимок памяти как раз доказывает, что программа одновременно никогда не обращается ко всем своим страницам. То есть это подтверждение возможности создания механизмов управления виртуальной памяти. Еще раз повторяю, такая возможность имеется исключительно благодаря тому, что действительно программа никогда не обращается ко всем своим страницам. Здесь программа очень небольшого объема, но видно, что она в общем-то обращается только к части страниц адресного пространства. Ну и как я уже сказала затраты вот они - на доске. Мы тратим время на страничное преобразование. Кроме того, мы тратим время на обслуживание страничных прерываний. Само название - управление памятью страницами по запросу говорит о том, что страницы загружаются в память, когда в них возникает необходимость, когда возникает страничное прерывание. Когда возникает страничное прерывание? Когда процессор обращается к команде или к данным, то есть по адресу, который отсутствует в физической памяти. То есть командам или данным, которые отсутствуют в физической памяти. Понятно, что такие данные и команды находятся на странице, которая не загружена в физическую память. Значит, в результате страничного преобразования система должны загрузить отсутствующую страницу в память. Очевидно, что пока такая страница не загружена в память, процесс блокируется. Все это огромные накладные расходы реализации виртуальной памяти. А выигрыш в чем? В технике не может быть затрат без выигрыша. А то че делать то?
Зачем делать хуже? В чем выигрыш?Выигрышем является увеличение мультизадачности. То есть большее количество программ может одновременно находится в физической памяти. Ну, тут уже об эффективности использования, конечно, тоже надо сказать, то есть в памяти находятся только те страницы, которые необходимы только в данный момент времени, но плата за это также очень высока. Необходимо обслуживать (подрубку? подборку?) этих страниц. Так сказать необходимо обслуживать их (что-то на непонятном) прерывания.
Замена страниц (page replacement)
Ну значит, замена страниц. По английски это будет page replacement. Следующее, что делать если вся память распределена? То есть все страницы физически заняты. Очевидно, чтобы загрузить в память новую страницу, надо выгрузить какую-то страницу из памяти. То, что называется paging'ом. Существует несколько подходов. Ну, оптимальный способ рассматривать бессмысленно, предполагается, что надо вытолкнуть такую страницу, которая не понадобится в ближайшее время. Такой информации у системы нет. (что-то тихо добавила 2-ая часть 06:26, но думаю мысль та же).
Выталкивание случайной страницы
Поэтому в качестве первого способа рассмотрим выталкивание случайной страницы. Самый простой способ, когда выталкивается, как бы, первая попавшаяся страница. Самый простой способ в реализации. Не считается дискриминационным, то есть любая страница может быть вытолкнута. Очевидные недостатки следующие: Может быть вытолкнута часто использующаяся страница или только что загруженная.
FIFO
Второй способ или вторая стратегия - FIFO. Выталкивается страница которая дольше всего находится в памяти. В отличие от первого способа, этот способ предполагает уже необходимость или присваивания каждой страницы временной метки, когда она была загружена в память, или организации связного списка типа очереди. Рассмотри модель на основе которой посмотрим ситуацию с этим способом, которая получила название - аномалия FIFO. Оказывается, существуют такие траектории загрузки страниц, когда увеличение памяти приводит не к уменьшению числа страничных прерываний, а к их увеличению, как ни странно. То есть понятно, априорно можно предположить, что увеличение доступного объема физической памяти, то есть увеличение количества физических страниц, должно привести к уменьшению числа страничных прерываний. Ну вот на простейшей модели демонстрируется, что это не так (видимо должна быть какая-то модель 2-ая часть 10:16) и увеличение памяти на определенных траекториях страниц приводит к увеличению числа страничных прерываний.
Модель очень простая, но от этого не менее замечательная, очень показательная. Сначала рассмотрим ситуацию, когда у нас есть три физические страницы.
(Кажется?), что в память последовательно загружаются страницы 4 3 2 1, 4 3 5, 4 3 2, 1 5 - это и называется траектория страниц. Соответственно нам надо загрузить 4 страницу в память, где есть пустой (Крым? фрейм? не услышал слово 2-ая часть 13:30). Значит в результате страничного прерывания мы загружаем 4 в память. Потом нам надо загрузить 3, потом надо загрузить 2, теперь нам надо загрузить 1 и у нас нет свободных страниц. Значит мы должны выгрузить 4. Надо снова загрузить 4 - мы выгружаем 3. Надо загрузить 3 - выгружаем 2. Надо загрузить 5 - выгружаем 1. Надо загрузить 4, 4 в памяти - это так называемая страничная удача. Значит страничное прерывание не выполняется. Оно не нужно. 3 надо загрузить в память, она в памяти - страничная удача. Но поскольку это очередь - ничего не меняется, все остается так, как было. 2 надо загрузить - 4 выгружаем. 1 надо загрузить - 3 выгружаем. 5 в памяти - страничная удача. Ну и у вас с вами (f? 2-ая часть 15:34) равно 9, значит 9 12-ти (называет какие то числа). Увеличиваем память на одну страницу, все то же самое(видимо тоже нужна схема 2-ая часть 15:50). Траектория та же. Делаем то же самое.
Ну мы видим, что несмотря на то, что мы предполагали, что увеличив память, число страничных прерываний сократится - оно увеличилось. Еще раз повторяю, действительно очень простая модель, но она очень показательная. Ну нельзя сказать, что FIFO не используется. Ну вот у него есть такая аномалия. Но это определенные траектории. Конечно, здесь выполнен подбор, но тем не менее это существует.
LRU
Третий алгоритм, способ, стратегия - LRU - least recently used. Из памяти выталкивается страница наименее используемая в последнее время, то есть страница, к которой дольше всего не было обращений.
Вернемся к FIFO и, опять же, отметим очевидные недостатки FIFO: то есть вытолкнуть только что загруженную страницу по FIFO нельзя, но какую страницу можно вытолкнуть? Часто используемую. Поэтому, естественно, стремление улучшить ситуацию привело к появлению вот этого алгоритма - least recently used - наименее используемая в последнее время. То есть уже из самого названия следует, что часто используемые страницы выталкиваться не будут. Для реализации этого алгоритма, опять же, можно использовать временные метки, но временные метки должны редактироваться при каждом обращении к странице. Или связный список, но страница должна перемещаться в конец списка, опять же, при каждом обращении к ней. Таким образом, в начале списка окажутся страницы, к которым дольше всего не было обращений. Ну давайте сразу определимся с ценой редактирования при каждом обращении, как часто мы обращаемся к странице. В каждой команде а то и несколько раз. Ну, если речь идет о чисто прямом отображении. То есть, в данном случае наличие этой страницы памяти значит вот это делается при каждом обращении. То есть мало того, что мы тратим время на само обращение к этой странице, неважно где, мы еще должны редактировать информацию об этой странице.Затратный метод. Давайте проведем его анализ. Ну, значит вам придется все перерисовать, а я попробую использовать наличествующую картинку. (нужна схема 2-ая часть 24:55) Уже не особо это, так сказать, выигрышно, но тем не менее. (пишет на доске)
Траектория та же, но со связным списком мы работаем по-другому.
Нам надо загрузить 4-ую страницу, она в памяти. Значит 4-ая страница перемещается в начало списка. Надо загрузить 3-ю, она в памяти, значит она будет перемещена в начало списка. 2-ю надо загрузить, соответственно мы выгрузим 5-ю. 1-ю надо загрузить - выгрузим 4-ю. 5-ю надо загрузить - выгрузим 3-ю. 4-ю надо загрузить, она в памяти (сначала сказала 3-ю, потом исправила на 4-ю), соответственно она переносится в конец списка. 3-ю надо загрузить, она в памяти - страничная удача. 5-ю надо загрузить - 2-ю выгружаем. 4-ю надо загрузить, она в памяти. 3-ю надо загрузить, она в памяти. 2-ю надо загрузить - 1-ю выгружаем. 1-ю надо загрузить - 5-ю выгружаем. 5-ю надо загрузить. Ну во-первых, давайте напряжемся интеллектуально. Что показывает эта картинка? (видимо все та же схема 2-ая часть 30:00 на всякий) Что невозможно предсказать какая страница понадобится в следующий момент времени. Вы видите как обидно мы, можно сказать, только недавно выгрузили 5-ю и она опять нам понадобилась. Только недавно выгрузили первую, она опять нам понадобилась. Модель, удивительная по своей простоте, демонстрирует то, что реально происходит в памяти. Ну, мы видим, что произошло так, как мы и предполагали - число страничных прерываний уменьшилось с увеличением объемов памяти. Но, как я уже сказала, затраты колоссальные. Еще если более внимательно посмотреть на эту картинку, то станет видно следующее: первые три строки модели с четырьмя страницами повторяют строки с тремя страницами. То есть этот способ обладает свойством включения. Свойство включения гласит: если какая-то страница выбрана при реализации объемом памяти M, то эта же страница при той же траектории будет выбрана, если память M + 1 страница.
Алгоритм LRU относится к классу стековых алгоритмов. Но затраты для его реализации, как я уже сказала, огромные. В чистом виде алгоритм LRU не используется. Почему он дает такие результаты? (ну кроме того, что он стековый) Он полностью соответствует свойству локальности, которое мы с вами сформулировали. Что наиболее вероятно обращение к странице, к которой мы обращались в последний момент времени. И если к странице долго не обращаться, то также очень вероятно, что к ней вообще не будет обращения.
LFU
LFU - least frequency used.
Наименее часто использующийся в последнее время. В этом алгоритме есть стратегия - контролируется частота использования страниц. Но, наименее часто использованной может оказаться только что загруженная страница. То есть она еще не успела набрать частоту обращений. Поэтому вероятность того, что она будет вытолкнута весьма велика.
NUR
NUR - not used recently.
В отличие от LFU, который является близким, но не совсем, NUR является аппроксимацией (LRU? 2-ая часть 37:44) Что такое апроксимация? Аппроксимировать - приближать. Очевидно, что сложности реализации LRU и в тоже время, так сказать, очевидная значимость этого алгоритма, привела к стремлению реализовать близкий алгоритм. Для этого к каждому кадру физической памяти приписывается (бит? 2-ая часть 38:34) обращения. Ну кадру или фрейму. Причем работа с этим битом выполняется следующим образом: когда в страницу загружается какой-то фрейм бит обращения устанавливается в 1. Причем при каждом обращении к странице, этот бит обращения обновляется. Периодически все биты обращения сбрасываются в 0. Когда в какой-то момент времени требуется вытеснить страницу, то ищется страница, у которой бит обращения 0, то есть страница, к которой не было обращений в последнее время. Ну, это последнее время - время последнего обнуления битов во всех страницах. Представить этого себе можно на простейшей схеме. (видимо нужна схема 2-ая часть 40:50) (пишет на доске)
Данная картинка показывает состояние памяти в момент после загрузки 5-ой страницы - 1-ый кадр. Соответственно указатель удаления показывает на эту страницу. Следующий момент, когда понадобится найти страницу для вытеснения, значит, она будет искаться начиная со следующих кадров, то есть по вот такому вот круговому принципу. Кроме бита обращения. Кстати я напоминаю, что в дескрипторах сегмента мы видели бит обращения. Кроме бита обращения вводится бит модификации, который устанавливается, если страница была модифицирована, (то есть в странице была определена запись? 2-ая часть 43:38)
Вопрос к вам. Какую страницу выгодно вытеснять? Модифицированную или немодифицированную? (Немодифицированную? 2-ая часть 43:55), так как Ее точная копия лежит на диске. То есть действительно не нужно выполнять запись этой страницы на диск, так как Ее точная копия находится на диске. При этом у нас два бита - возможны четыре ситуации. Ну вызывает вопрос вот эта ситуации. (видимо есть какая-то схема 2-ая часть 45:20)
Обращения не было, модификация была. Но, если вспомнить, что биты обращения время от времени сбрасываются в 0, то есть модификация была до сброса всех битов обращения в 0. Очевидно, что, как я уже сказала, для вытеснения лучше выбирать немодифицированную (тут запись обрывается) видимо страницу.