Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Создание прибыльного сайта для начинающих" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Интернет для Delphi-программиста 60
Интернет для Delphi программиста.Выпуск : № 60 Здравствуйте уважаемые подписчики рассылки "Интернет для Delphi программиста". Данная рассылка предназначена для всех кого интересует Delphi, здесь будут выкладываться ссылки на различные ресурсы интернета так или иначе связанные с Delphi: книги, исходники, программы... Изучайте Delphi один из лучших языков программирования!!! ЗАДАТЬ ВОПРОС : Правила
рассылки: Новые вопросы.
Ответы.
Статья: "Принципы работы с памятью в системе Windows 32." 1. ВведениеВ данной статье изучаются принципы работы с памятью в системе Windows 32. Исследуется проблема накопления потоковых данных в специальных потоковых хранилищах. Работа с памятью является одной из важнейших функций любой программы. Выделение участков памяти для структур программы должно быть эффективным, поэтому программист должен хорошо разбираться в особенностях этого процесса. В статье приводятся только основные принципы работы с памятью в системе Windows 32. Для подробного изучения всех тонкостей этого сложного процесса читатель может обратиться к специальной литературе. Особенно хочется отметить книгу: Дж.Рихтер, "Windows для профессионалов". 2. Организация виртуальной памяти в WindowsКак известно, Windows 32 - тридцатидвуразрядная операционная система (число 32 как раз это и обозначает). Прежде всего, из этого следует, что запущенная программа может адресовать линейное адресное пространство размером 2^32 байт = 4 ГБ, при этом адресация производится при помощи тридцатидвуразрядных регистров-указателей. Каждый запущенный в системе процесс обладает своим собственным адресным пространством, каждое из которых не пересекается с адресными пространствами других процессов. Распределение системных областей в адресном пространстве систем Windows 95/98 и Windows NT различно. Программа может адресовать любую ячейку памяти в диапазоне адресов своего адресного пространства. Однако, это не значит, что программа может записать или считать данные из этой ячейки. Адресное пространство в Windows - виртуально, оно не связано напрямую с физическим пространством оперативной памяти вашего компьютера. Механизм выделения памяти в Windows состоит из двух фаз. Первая фаза выделения памяти состоит в резервировании (захвате) участка необходимого размера в адресном пространстве процесса. При этом не выделяется ни байта реальной памяти (не считая системных структур ядра). Вы можете спокойно зарезервировать участок адресного пространства размером 100 мегабайт, и это ничего не будет стоить системе. Вы можете указать какие адреса вы хотели бы занять, а можете предоставить выбор участка необходимого размера самой системе. Стоит отметить, что адресное пространство резервируется с гранулярностью 64 кБ. Это значит, что несмотря на указанные вами адреса, базовый адрес реально зарезервированного участка памяти будет кратен 64 кБ. При резервировании участка в адресном пространстве можно указать желаемый атрибут, который регулирует доступ к этой памяти: запись данных, чтение данных, выполнение кода или комбинацию этих признаков. Нарушение правил доступа к памяти приводит к генерации системой исключения. Вторая фаза выделения памяти в Windows - это выделение реальной, физической памяти в зарезервированный участок виртуального адресного пространства. На этом этапе системой выделяется реальная память, со всеми вытекающими из этого последствиями. Выделение реальной памяти также гранулярно. Минимальный блок реальной памяти, которым оперирует система, и который можно выделить, называется страницей памяти. Размер страницы зависит от типа операционной системы и составляет для Windows 95/98 - 4 кБ, а для Windows NT - 8 кБ. Гранулярность при резервировании участка памяти и при выделении реальной памяти призвана облегчить нагрузку на ядро системы. Выделение реальной памяти происходит постранично, при этом существует возможность выделения произвольного количества страниц в произвольные (кратные размеру страницы) адреса заранее зарезервированного участка адресного пространства процесса. Каждой странице может быть назначен свой собственный атрибут доступа. Желательно указывать тот же самый атрибут, что имеет зарезервированный участок адресного пространства в котором происходит выделение страницы реальной памяти. Важным моментом в механизме выделения памяти является механизм динамической выгрузки и загрузки страниц памяти. В самом деле, современный компьютер имеет оперативную память объемом 16-256 МБ, а для совместной работы нескольких программ необходимо гораздо больше. Windows, как и большинство современных операционных систем, выгружает страницы памяти, к которым давно не было обращений, на жесткий диск в так называемый своп-файл. При этом размер реальной памяти, доступной для программ, становиться равным суммарному объему оперативной памяти и своп-файла. По возможности, система старается держать все страницы в оперативной памяти, однако когда суммарный размер выделенных всеми процессами страниц превышает ее размер, система выгружает страницы с давним доступом на диск, а на их месте выделяет новые страницы. Если же выгруженная на диск страница затребуется владеющим ею процессом, система освободит для нее место в оперативной памяти путем выгрузки редко используемой страницы, загрузит затребованную страницу на ее место и вернет управление процессу. Весь механизм динамической загрузки и выгрузки страниц абсолютно прозрачен для процессов, а реализация этого механизма полностью обеспечивается операционной системой. Процесс может абсолютно ничего не знать о существовании такого механизма - он обращается к своим ячейкам памяти, а система автоматически выгружает редко используемые страницы и загружает необходимые страницы; процесс может только регулировать некоторые нюансы работы этого механизма. На основании вышеперечисленного можно сделать следующие выводы:
3. Кучи и менеджеры кучАлгоритмы современных программ используют механизмы выделения и освобождения памяти очень интенсивно. Строки, динамические массивы, объекты, структуры, буфера - выделение и освобождение этих элементов происходит очень часто, при этом оказывается, что все эти элементы имеют небольшой размер. Выделение у системы большого количества объектов небольшого размера оказывается неэффективным по следующим причинам.
Решение этой проблемы организуется следующим образом: у операционной системы выделяется достаточно большой участок памяти, а уже из него для прикладной программы "нарезаются" небольшие участки. Такая организация называется кучей, а механизм, который следит за выделением и освобождением участков памяти называется менеджером кучи. Куча позволяет решить как проблему потери производительности - менеджер кучи может функционировать на уровне прикладной программы, так и проблему гранулярности - менеджер запрашивает у системы один большой участок памяти. Windows имеет свою собственную реализацию менеджера кучи, который позволяет приложениям создавать, уничтожать кучи, а также производить с ними операции выделения и освобождения памяти в куче. Кроме того, для каждого вновь создаваемого процесса Windows специально создает кучу по умолчанию, которая используется при работе API функций, а также может быть использована прикладной программой. Все создаваемые Windows кучи потоко-безопасны, то есть существует возможность обращения к одной и той же куче из разных потоков одновременно. Инженеры компании Borland по видимому не доверяют инженерам компании Microsoft, поэтому каждая программа на Delphi имеет свою собственную реализацию менеджера кучи, которая определена в системных модулях. Такое решение аргументируется инженерами Borland тем, что стандартный менеджер кучи Windows не обеспечивает достаточно эффективную работу с памятью. Конечно, как и любая Windows-программа, программа на Delphi имеет стандартную кучу по умолчанию, которую создает для нее система, однако функции New, Release, GetMem, FreeMem и некоторые другие оперируют с собственной реализацией менеджера куч. Менеджер кучи Delphi резервирует блоки адресного пространства размером 1 Мб, а выделяет блоки реальной памяти размером 16 Кб. Также вы можете написать и установить свою реализацию менеджера куч, если не доверяете ни инженерам Borland, ни инженерам Microsoft - для этого имеются все необходимые функции. Хотя куча совершенно не предназначена для выделения больших участков памяти, запрос выделения большого участка у кучи не приведет к ошибке. Куча просто перенаправит ваш запрос операционной системе и вернет указатель на выделенный ею участок памяти. 4. Группы функций работы с памятьюВ главе описываются группы базовых функций работы с памятью, которые доступны для программиста на Delphi. Включены описания как API-фукнций, так и Delphi-функций. Delphi-функцииNew(), Dispose() GetMem(), FreeMem() API-функцииHeapCreate(), HeapDestroy(), ... LocalAlloc(), LocalFree(), ... , GlobalAlloc(), GlobalFree(), ... VirtualAlloc(), VirtualFree(), ... 5. Потоковые хранилищаОчень часто во многих программах встает проблема накопления потока поступающих данных. Например, это может быть запись звука, запись сигналов с датчиков, накопление данных с модема, коммуникационного порта, прием данных по сети и так далее. Если объем накапливаемых данных небольшой и заранее точно известен, то такая задача решается элементарно - под буфер выделяется блок памяти и эта память постепенно заполняется. Если же размер требуемого буфера достаточно большой, то выделение его полностью в самом начале может быть неэффективным - запись потока может прерваться гораздо раньше, а если же размер его неизвестен заранее, например когда запись данных останавливается по какому-либо внешнему сигналу, то встает проблема о выборе размера выделяемого блока. В таких случаях используют динамические хранилища. В Delphi такими хранилищами являются динамические массивы, объект TMemoryStream, динамическое перераспределение памяти. Все эти хранилища работают на одном и том же принципе: под хранение данных выделяется блок памяти и поступающие данные последовательно записываются в этот блок, когда этот блок заполняется полностью, он перераспределяется с некоторым запасом (размер его увеличивается, а старые данные остаются). После того как каждый новый блок заполняется полностью он снова перераспределяется по мере поступления новых данных. Перераспределение памяти занимает много ресурсов само по себе, а так как оно выполняется еще и в куче, то можно считать его вдвойне неэффективным, особенно если размеры перераспределяемых блоков становятся очень большими. Динамические массивы и динамическое перераспределение памяти используют менеджер кучи Delphi, а объект TMemoryStream использует стандартный менеджер кучи Windows. Кроме того постоянное перераспределение участков памяти с разными размерами приводит к сильной дефрагментации памяти компьютера, что приводит к замедлению работы компьютера, а в конечном счете и к блокировке его работы. Для решения проблемы накопления данных автором были разработаны два объекта накопления данных, основанные на двух разных принципах и имеющих разные характеристики.
TLinearStorageЕсли размер буфера большой, но максимально возможный размер известен (например если есть ограничение на объем записываемых данных), то можно поступить следующим образом. В адресном пространстве процесса резервируется блок памяти необходимого размера, напомним, что такая операция не занимает ресурсов у системы. Затем по мере необходимости в этом зарезервированном участке памяти, по мере необходимости, последовательно выделяются страницы реальной памяти. Достоинством такого метода является линейное расположение ячеек в памяти друг за другом, то есть к такому хранилищу можно обращаться как к обычному линейному массиву. Недостатком - необходимость указания максимального размера. TSectionStorageЕсли размер буфера заранее неизвестен (ограничен лишь размером доступной реальной памяти), то предыдущее решение не подходит. В этом случае можно предложить другое решение. По мере необходимости, у системы можно запрашивать участки памяти одинакового размера и записывать в них поступающие данные. При этом буфер не будет иметь линейного адресного пространства, а будет состоять из одноразмерных "лоскутов" памяти - для вычислительного алгоритма такая организация буфера может стать серьезной помехой. Достоинством же такого решения является отсутствие необходимости изначально указывать какой либо размер буфера. Если предполагается интенсивное увеличение-уменьшение хранилища, причем желательно, чтобы приращения были небольшими, то можно запрашивать память не у системы, а у стандартного менеджера кучи Windows, который создается для каждого хранилища отдельно. При этом, менеджер кучи выполняет роль кэша страниц памяти, увеличивая производительность. Дополнительно, каждое хранилище имеет функции записи и чтения в стандартные потоки Delphi с упаковкой. Упаковка производится по стандартным алгоритмам библиотеки ZLIB. 6. Библиотека потоковых хранилищTBaseStorage - базовый классОба хранилища, которые будут
рассматриваться в дальнейшем, основаны
на одном абстрактом базовом классе и
имеют схожие свойства и методы.
Линейное хранилищеЛинейное хранилище имеет линейное
адресное пространство буфера, однако
нуждается в указании максимальной
емкости, пусть даже и очень большой.
Секционное хранилищеСекционное хранилище хранит данные в
кусочно-линейном буфере состоящем из
участков одинакового размера. Хранилище
не требует указания максимальной
емкости, но взамен не позволяет
обращаться к элементам как к массиву
данных.
Вообще с объектом TMemoryStream связаны странные, необъяснимые истории. Как-то раз автор имел несчастье использовать этот объект в одной из своих программ для накопления потока данных с модема. Через некоторое время после запуска программа зависала сама и, кроме того, подвешивала Windows NT. Анализ с помощью диспетчера задач показал, что в процессе жизнедеятельности программы, она занимает все новые и новые участки памяти. Поиск ошибок ни к чему ни привел, однако в конце концов пришлось обратить внимание на странности в поведении объекта TMemoryStream. Пришлось создать свой поток THeapStream путем формальной замены функций семейства Global... на функции GetMem, FreeMem, ReallocMem - то есть заменой стандартного менеджера кучи Windows на менеджер кучи Delphi. После этого все странности при работе программы исчезли. Скорее всего это было связано с очень сильной дефрагментацией памяти, так как заполнение объекта TMemoryStream данными приводит к постоянному перераспределению участков памяти с разными размерами. От такой дефрагментации помогает только перезагрузка компьютера. Компоненты: Компонент представляет собой мультимедийный таймер, скорость (точность) работы которого намного выше по сравнению с системным таймером (TTimer). Кроме того, он имеет два режима работы: 1) ttOneshot - отрабатывает один раз и останавливается. 2) ttPeriodic - в этом режиме компонент ведет себя как стандартный TTimer. UpListView [D6] (обновился) Компонент является наследником класса TListView. Его основное назначение, выводить картинку в заголовке таблицы в режиме vsReport. В компоненте появилось четыре новых свойства и три новых события. Более подробно читайте в ReadMe.txt в архиве. К компоненту прилагается пример. Если Вы хотите нарисовать на форме трёхмерный куб, то этот компонент позволит Вам это осуществить очень легко. Компонент позволяет получать информацию о системных дисках.Hard Disks, local, floppy disk, network drives, RAM Drives... Может получать информации о:
AlphaControls Lite Edition v.4.42 Пакет содержит 13 полностью бесплатных и полнофункциональных компонентов из пакет AlphaControls (TsSkinManager, TsSkinProvider, TsEdit, TsCheckBox, TsPanel, TsButton, TsScrollBar, TsLabel, TsWebLabel, TsBitBtn, TsComboBox, TsListBox и TsGauge). Используя эти компоненты, вы можете узнать основные особенности AlphaControls. Небольшой и пример и его исходный код включены в архив.Особенности:
Этот код позволит обычному компоненту Tlabel работать с гиперссылками. Он поддерживает большинство часто употребляемых URL и Skype. Просто скомпилировать и установить компонент, выберите тип uкl (http:, https:, ftp:, mailto:, file:, или skype:) и введите название ссылки. Когда пользователь нажмёт на надпись выполниться соответствующая команда. Вы можете добавлять свои команды ко всем типам url. Пример приложения, включённый в архив, показывает как можно использовать http:, skype: и mailto: Этот компонент был разработан, используя Delphi7 и не требует «специальных» модулей, поэтому он должен компилироваться и на других версиях Delphi. Полный исходный код также включён. M3DGraphics1 модуль для Delphi. Позволяет рисовать 3-х мерные фигуры. Интересные и полезные сайты по Delphi: Если Вы хотите, чтобы Ваш сайт был в этом разделе пишите.
Немного юмора: :))
Дружественные рассылки: Все
кто хочет изучить Delphi и реально
научиться писать свои программы, ЦПИ "Эверест"
поможет Вам. 10 причин в пользу платного обучения в ЦПИ "Эверест"… 1. Когда Вы
платите деньги-
появляется дополнительный стимул
против лени: надо учиться, ведь деньги
уже уплачены….
5. Стоимость обучения
одного месяца в ЦПИ "Эверест"
сравнима с ценой хорошей книги. Но часто
ли Вам попадались книги, рассчитанные
именно на Вас. Мы же работаем
индивидуально.
8. А это значит, что …Мы
предлагаем получить "высшее
образование" - профессию
программиста всего за
1 год и 144 доллара, любой ВУЗ
попросит в 3 раза больше за один только
семестр. По всем вопросам обращайтесь ко мне. Если вы встретили в интернете
интересный сайт или статью, да и вообще, что угодно
связанное с Delphi, поделитесь ссылкой. Предложения, критику и пожелания пишите на e-mail. |
В избранное | ||