УПРАВЛЕНИЕ ПАМЯТЬЮ
Эта глава применима только к системам MS-DOS/PS-DOS, базовыми си- стемами UNIX она может быть игнорирована: в системе UNIX программы LISP и объём данных практически неограничены .
Переменные , пользовательские определители ( user- defined) фун- кций и стандартные функции, описанные в этом руководстве, все помещают- ся в памяти вашего компьютера только на время сеанса редактирования в системе AutoCAD. Когда AutoLISP загружен , он требует для себя два больших участка памяти. Первый , называемый heap (или nodes ), это участок , на котором хранятся все функции и переменные , больше пере- менных и функций есть у вас (и больше комплексов ваших функций) -больший heap space ( участок памяти) будет использован. Второй участок, назы- ваемый stack ( стек ) , содержит аргументы функций и частично результа- ты ; глубже "клубок" функций или больше повторений выполнения ваших фун- кций - большая часть стека ( stack space ) использована.
По умолчанию размеры участков памяти:
heap 5.000 bytes stack 5.000 bytes
AutoLISP, работая с AutoCADом, не может менять размеры участ- ков памяти heap и stack. Если вы , вычисляя достачно большое количество функций и переменных , израсходуете весь участок памяти heap, AutoLISP выведет на дисплей сообщение об ошибке:
Insufficient node space Недостаточное node пространство
и закончит выполнение текущей функции. Если недостаточно памяти , чтобы загрузить AutoLISP , когда вы в AutoCADе , на экран дисплея будет вы- ведено сообщение:
Insufficient memory - AutoLISP disabled Недостаточно памяти - AutoLISP невозможен
AutoLISP не будет функционировать до тех пор, пока память не будет предоставлена , и AutoCAD выполнится снова.
6. 1. Устанавливаемые AutoLISPом требования к памяти
Если вы опытный программист и хорошо знакомы с концепцией исполь- зования "heap" и "stack" областей памяти в языках программирования , вы можете по желанию использовать команду "SET" системы DOS, чтобы после этого AutoLISP получил достаточную память для участков heap и stack. Например, команды:
C>SET LISPHEAP=25000 C>SET LISPSTACK=10000
говорят AutoLISPу резервировать 25000 байтов памяти для участка heap, и 10000 байтов для участка stack. Полный объем памяти для двух участков не должен превышать 45000 байт.Если вы хотите,вы можете поместить утверждения , подобные приведенным выше , в ваш файл " autoexec.bat", и они будут выполняться всегда , когда вы включаете ваш компьютер. Эти команды "SET" эффективны только в AutoLISPе , они не являются при- чиной , того, что память вашего компьютера будет "погибшей"(" lost "), пока AutoLISP не загружен.
6. 2. Восстанавливаемое NODE SPACE(участок памяти node)
Вы можете обнаружить, что некоторые созданные вами функции и пе- ременные нужны вам только на некоторое время. Когда они вам бу- дут уже не нужны, вы можете эффективно " не обнаружить" их, присваивая им значение "nil". Например, если вы загрузились и использовали функцию с именем SETUP , а дальше в ней не нуждаетесь , вы можете:
(setq setup nil),
чтобы избавиться от нее. Node (heap) участок памяти , используемый этой функцией , восстановится, давая возможность использовать его другими функциями и переменными.
Если вы хотите почистить(удалить) все функции и переменные , ко- торые вы загрузили или определили во время этого сеанса редактирования, это тоже легко можно сделать. AutoLISP обслуживает список с именем ATOMLIST, который первоначально содержит имена всех системных ( system- defined) функций и переменных. ( Если вы хотите видеть его содержание, введите только "!atomlist" в ответ на подсказку AutoCADа "Command:")
Как только вы создаете новые функции и переменные , их имена заносятся в оглавление ATOMLIST. Вы можете изъять любое ,обозначенное вами, из того что есть в оригинале, прерыванием ATOMLISTа . Будьте внимательны, однако, не прерывайте системных функций , иначе вы окажетесь в тупике.
Если вы поместите следующую функцию в ваш "acad.lsp" файл:
(defun C:CLEAN () (setq atomlist (member 'C:CLEAN atomlist)) 'DONE )
у вас будет возможность ввести команду CLEAN , всегда , когда вы хотите сделать ATOMLIST аккуратным и получить обратно участок памяти node, используемый всеми вашими функциями и переменными. Если C:CLEAN послед- няя функция в вашем "acad.lsp" файле , функции, которые вы определяете ранее в файле, будут сохранены , когда вы введете CLEAN. Функция CLEAN сбрасывает только подпоследовательно определяемые( subsequently-defined) функции и переменные, таким образом, все , что вы в " acad.lsp" опре- делили раньше, обработается как системно определяемые функции.
ЗАПОМНИТЕ. Механизм ATOMLIST нестандартная особенность LISPа и может быть изменена в будущих версиях AutoLISPа. К тому же, техни- ка прерывания ATOMLISTа не може т быть использована , когда имеется возможность листания виртуальных функций. Смотри следующий раздел.
6. 3. Виртуальные страничные функции
Если применение вашего AutoLISPа становится слишком большим , чтобы быть впору имеющемуся участку памяти node (установленному пере- менной SET в LISPHEAP , как описано выше), вы можете использовать перелистыватель виртуальной функции AutoLISPа, чтобы позволить рост ва- шей программы. Чтобы сделать это, просто выполните функцию:
(vmon)
перед первым DEFUN в вашей программе. Это позволит виртуальной функции разбить память на страницы, для остатка сеанса AutoCAD Drawing Editor. Однажды позволенная , функция разбиения памяти на страницы не отключает- ся. Только функции, созданные через функции DEFUN ,следующие за функцией VMON, подходят для разбиения памяти на страницы , а, если у вас функции DEFUN перед VMON , они не будут разбивать память на страницы и еще могут вызвать на терминал сообщение:
"Insufficient node space" Недостаточно памяти node
После того , как функция VMON выполнится, AutoLISP будет перелис- тывать страницы редко используемых функций, всякий раз когда они за- пускаются из памяти, и автоматически читать их снова, когда они понадо- бятся. Вам не нужно беспокоиться об этом перелистывании,так как оно уп- равляется автоматически, и это ясно из вашей программы.Эти функции вре- менно перекачиваются в файл , через который управляется файл перелисты- вателя страниц AutoCADа. Итак , когда вы имеете достаточно расширенную или продленную память, обычно эта память будет перекачивать функции и выдаст результат намного быстрее , чем свопинг(перекачка)на диск.
Запомните, что система с виртуальной памятью только листает функ- ции: однако, вы должны иметь достаточный участок node памяти для разме- щения всех списков (data lists) , использующихся в вашей программе, а также функций и имен переменных. Следовательно, хотя листание страниц позволяет прогнать большую программу со много меньшей памятью, вы ,одна- ко, должны установить оптимальный размер участка heap и набор LISPHEAP соответственно. То же самое относится к размеру участка stack и к набо- ру LISPSTACK при работе с виртуальной памятью.
Технические замечания
Следующая информация полезна только опытным хакерам (программис- там ) LISPа. Новички и те, кто играют, как правило, могут( и должны) иг- норировать эту дискуссию.
После того , как функция VMON выполнится, все функции DEFUN зани- мают новый участок node памяти, называемый таблица страниц (page table), в начале каждого списка функции. Этот node участок добавляется перед списком, содержащим формальные аргументы. Участок памяти page table node используется исключительно,как перелистыватель страниц ,и в любом случае, им нельзя манипулировать пользователю программ. Функция TYPE возвращает PAGETB в эти участки памяти node.
Когда программа AutoLISP загружается из участка памяти node, ме- ньше всего используемая функция сбрасывается записью ее в стра- ничный файл (paging file) , сохраняя адрес страничного файла в таблице страниц, и освобождая весь участок памяти node, занимаемый функцией, следующей за таблицей страниц. В таблице страниц маркируется та функция, которая сброшена. Когда сброшенная функция вычислена, она снова считыва- ется из страничного файла( возможно откачивание других функций) по при- оритету выполнения. Когда функция списана из страничного файла, последующие откачки просто освобождают этот участок hode памяти. Нет необходимости удалять функцию , так как она всегда присутствует в файле.
В AutoLISPе функции, созданные с помощью DEFUN, являются просто списками, и ими можно манипулировать как со списками. Программы , которые делают это , должны быть осведомлены об операции перелистывания страниц ( или не применяйте VMON). Прежде всего,функции, создаваемые с помощью функции DEFUN, имеют в начале участок памяти node таблицы страниц ( page table), так что , вы должны перескочить его, если будете сканировать фу- нкцию. Если вы создаете функцию сами для себя , как список( обходя DEFUN), она будет работать прекрасно,но она не подойдет для свопинга ( перекачивания) , поэтому вы можете легко запустить ее из памяти, если вам это удобнее. Наоборот, вы можете поместить функцию в память , переопределяя ее без таблицы страниц. Например, чтобы помес- тить функцию, определенную DEFUNом с именем ZORP,в память,вы должны ис- пользовать:
(setq zorp (cdr zorp))
чтобы удалить применение таблицы страниц. Таблицы страниц печатаются про- сто как пробел , когда вы используете функцию PRINT. Вы можете определить, когда функция перекачиваема, проверив, имеется ли пробел после первой левой скобки: если так , она перекачиваема.
Если вы пытаетесь сканировать функцию, как данные, и откачи- вать ее, вы должны найти только таблицу страниц в списке функции. Проход- ная функция не будет перекачена- только вычисливши ее, можно сделать это. Итак, если вы создаете функции и модифицируете их с хитростью, организуй- те их как списки , вместо использования функции DEFUN, или используйте трюк,приведенный выше, чтобы поместить их в память.
Список символов, известных AutoLISPу, называется ATOMLIST. Есть возможность хитрой программе манипулировать этим списком, чтобы исправить пробел или сканировать все символы. ( Как отмечено в предыдущей главе, это не стандартная особенность LISPа, и она может быть изменена в буду- щих версиях AutoLISPа.) Когда функция откачивается , она преобра- зуется в пути , это предполагает что ATOMLIST, не будет изменен до тех пор, пока функция не откачается ( если разбиения памяти на страницы нет на этом пути, функция занимает гораздо больше места на диске и идет в пять раз медленней). Чтобы быть уверенным , что ATOMLIST не изменится, когда листание действительно имеется, доступ к ATOMLISTу блокируется перемещением ATOMLISTа из списка символов ,доступнх пользователю. Если вы используете виртуальную функцию листания страниц, оставьте ATOMLIST в покое.
Если вы действительно хотите , чтобы у вас были неприятности, вы можете это сделать. Вы можете создать свою собственную функцию, включая таблицу страниц, из любой другой функции. Вы должны присвоить ATOMLISTу собственную переменную и изменить ее после того , как AutoLISP стартует для листания страниц. Вы можете даже придумать что-нибудь бо- лее творческое и ужасное. Однако , такое поведение может быть отмщено разрушением вашей программы; это не может повредить AutoLISPу или Auto- CADу. Итак, если вы хотите нести потери, вперед.