Сведения о таблицах Atom

Таблица atom — это системная таблица , в которой хранятся строки и соответствующие идентификаторы. Приложение помещает строку в таблицу atom и получает 16-разрядное целое число, называемое атомом, которое можно использовать для доступа к строке. Строка, которая была помещена в таблицу atom, называется именем атома.

Система предоставляет ряд таблиц atom. Каждая таблица atom служит другой целью. Например, приложения Dynamic Data Exchange (DDE) используют глобальную таблицу atom для совместного использования строк имен элементов и разделов с другими приложениями. Вместо передачи фактических строк приложение DDE передает глобальные атомы своему партнерскому приложению. Партнер использует атомы для получения строк из таблицы atom.

Приложения могут использовать локальные таблицы atom для хранения собственных связей имен элементов.

В системе используются таблицы atom, которые не доступны напрямую приложениям. Однако приложение использует эти атомы при вызове различных функций. Например, зарегистрированные форматы буфера обмена хранятся во внутренней таблице atom, используемой системой. Приложение добавляет атомы в эту таблицу atom с помощью функции RegisterClipboardFormat . Кроме того, зарегистрированные классы хранятся в внутренней таблице atom, используемой системой. Приложение добавляет атомы в эту таблицу atom с помощью функции RegisterClass или RegisterClassEx.

В этом разделе рассматриваются следующие разделы.

Глобальная таблица Atom

Глобальная таблица atom доступна всем приложениям. Когда приложение помещает строку в глобальную таблицу atom, система создает атом, уникальный для всей системы. Любое приложение, которое имеет атом, может получить строку, которую он идентифицирует, запрашивая глобальную таблицу atom.

Приложение, определяющее частный формат данных DDE для совместного использования данных с другими приложениями, должно поместить имя формата в глобальную таблицу atom. Этот метод предотвращает конфликты с именами форматов, определенных системой или другими приложениями, и делает идентификаторы (атомы) для сообщений или форматов доступными для других приложений.

Таблица User Atom

Помимо глобальной таблицы atom, пользовательская таблица atom — это другая системная таблица atom, которая также используется во всех процессах. Таблица atom пользователя используется для небольшого количества сценариев, внутренних для win32k; Например, имена модулей Windows, известные строки в win32k, форматах OLE и т. д. Хотя приложения не взаимодействуют с таблицей atom пользователя напрямую, они вызывают несколько API, например RegisterClass, RegisterWindowMessage и RegisterClipboardFormat, которые добавляют записи в таблицу user atom. Записи, добавленные RegisterClass с помощью UnregisterClass, можно удалить. Однако записи, добавленные RegisterWindowMessage и RegisterClipboardFormat не удаляются до окончания сеанса. Если в таблице atom пользователя больше нет места, а строка, передаваемая в таблице, еще не находится в таблице, вызов завершится ошибкой.

Размер таблицы Atom

Многие критически важные API, включая CreateWindow, полагаются на атомы пользователей. Таким образом, нехватка пространства в таблице atom пользователя приведет к серьезным проблемам; Например, все приложения могут не запускаться. Ниже приведены некоторые рекомендации по обеспечению эффективного использования таблиц atom и сохранения надежности и производительности приложения и системы:

  1. Необходимо ограничить использование пользовательской таблицы atom в приложении. Хранение уникальных строк с помощью ТАКИх API RegisterClassRegisterWindowMessageили RegisterClipboardFormat занимает место в таблице user atom, которая используется глобально другими приложениями для регистрации классов окон с помощью строк. Если это возможно, следует использовать AddAtom DeleteAtom/ для хранения строк в локальной таблице атомов или GlobalAddAtom GlobalDeleteAtom/, если атомы необходимы между процессами.

  2. Если в приложении возникают проблемы с таблицами atom пользователя, можно изучить первопричину, подключив отладчик ядра и прервав процесс при вызовах UserAddAtomEx (bae1 win32kbase!UserAddAtomEx /p <eprocess> "kc10;g"). user32! Найдите вызовы, чтобы увидеть, какой API вызывается. Методология аналогична обнаружению проблем с глобальной таблицей atom, описанной в статье "Определение утечки глобальных таблиц Atom". Другим способом дампа содержимого таблицы atom пользователя является вызов GetClipboardFormatName в диапазоне возможных атомов от 0xC000 до 0xFFFF. Если общее число атомов постоянно растет во время работы приложения или не возвращается к базовым данным при закрытии приложения, возникает проблема.

Локальные таблицы Atom

Приложение может использовать локальную таблицу atom для эффективного управления большим количеством строк, используемых только в приложении. Эти строки и связанные атомы доступны только приложению, создавшего таблицу.

Приложение, требующее той же строки в ряде структур, может уменьшить использование памяти с помощью локальной таблицы atom. Вместо копирования строки в каждую структуру приложение может поместить строку в таблицу atom и включить полученный атом в структуры. Таким образом, строка отображается только один раз в памяти, но может использоваться много раз в приложении.

Приложения также могут использовать локальные таблицы atom для экономии времени при поиске определенной строки. Чтобы выполнить поиск, приложению нужно поместить только строку поиска в таблицу atom и сравнить результирующий атом с атомами в соответствующих структурах. Сравнение атомов обычно быстрее, чем сравнение строк.

Таблицы Atom реализуются как хэш-таблицы. По умолчанию локальная таблица atom использует 37 контейнеров для хэш-таблицы. Однако можно изменить количество контейнеров, используемых путем вызова функции InitAtomTable. Однако если приложение вызывает InitAtomTable, оно должно сделать это перед вызовом других функций управления атомами.

Типы Atom

Приложения могут создавать два типа атомов: строковые атомы и целые атомы. Значения целых атомов и строковых атомов не перекрываются, поэтому оба типа атомов могут использоваться в одном блоке кода.

Некоторые функции принимают строки или атомы в качестве параметров. При передаче атома в эти функции приложение может использовать макрос MAKEINTATOM для преобразования атома в форму, которую можно использовать функцией.

В следующих разделах описаны типы атомов.

Атомы строк

Когда приложения передают строки, завершаемые null, в функции GlobalAddAtom, AddAtom, GlobalFindAtom и FindAtom, они получают строковые атомы (16-разрядные целые числа) в ответ. Строковые атомы имеют следующие свойства:

  • Значения строковых атомов находятся в диапазоне 0xC000 (MAXINTATOM) через 0xFFFF.
  • Регистр не имеет большого значения в поиске имени атома в таблице atom. Кроме того, вся строка должна совпадать в операции поиска; сопоставление подстроки не выполняется.
  • Строка, связанная с атомом строки, не может превышать 255 байтов. Это ограничение применяется ко всем функциям atom.
  • Число ссылок связано с каждым именем атома. Число увеличивается каждый раз, когда имя атома добавляется в таблицу и уменьшается каждый раз, когда имя атома удаляется из него. Это запрещает разным пользователям одного и того же строкового атома уничтожать имена атомов друг друга. Если число ссылок для имени атома равно нулю, система удаляет атом и имя атома из таблицы.

Целые атомы

Целые атомы отличаются от строковых атомов следующим образом:

  • Значения целых атомов находятся в диапазоне 0x0001 через 0xBFFF (MAXINTATOM–1).
  • Строковое представление целочисленного атома равно #dd, где значения, представленные d, являются десятичными цифрами. Начальные нули игнорируются.
  • Количество ссылок или затраты на хранение, связанные с целым атомом, отсутствуют.

Число создания и использования Atom

Приложение создает локальный атом, вызывая функцию AddAtom; она создает глобальный атом, вызывая функцию GlobalAddAtom. Обе функции требуют указателя на строку. Система выполняет поиск соответствующей таблицы atom для строки и возвращает соответствующий атом приложению. В случае с атомом строки, если строка уже находится в таблице atom, система увеличивает число ссылок для строки во время этого процесса.

Повторяющиеся вызовы для добавления одного и того же имени атома возвращают один и тот же атом. Если имя атома не существует в таблице при вызове AddAtom , имя атома добавляется в таблицу и возвращается новый атом. Если он является строковым атомом, его число ссылок также имеет одно значение.

Приложение должно вызывать функцию DeleteAtom, если она больше не должна использовать локальный атом; она должна вызывать функцию GlobalDeleteAtom, если она больше не нуждается в глобальном атоме. В случае с атомом строки любой из этих функций уменьшает количество ссылок соответствующего атома на один. Когда число ссылок достигает нуля, система удаляет имя атома из таблицы.

Имя атома строкового атома остается в глобальной таблице atom до тех пор, пока его число ссылок больше нуля, даже после того, как приложение, помещенное в таблицу, завершает работу. Локальная таблица атомов уничтожается при завершении связанного приложения независимо от количества ссылок атомов в таблице.

Запросы Atom-Table

Приложение может определить, уже находится ли определенная строка в таблице atom с помощью функции FindAtom или GlobalFindAtom. Эти функции выполняют поиск таблицы atom для указанной строки и, если строка есть, возвращает соответствующий атом.

Приложение может использовать функцию GetAtomName или GlobalGetAtomName для получения строки atom-name из таблицы atom, если приложение имеет атом, соответствующий запрашиваемой строке. Обе функции копируют строку atom-name указанного атома в буфер и возвращают длину скопированной строки. GetAtomName извлекает строку atom-name из локальной таблицы atom, а GlobalGetAtomName извлекает строку atom-name из глобальной таблицы atom.

Форматы строк Atom

Функции AddAtom, GlobalAddAtom, FindAtom и GlobalFindAtom принимают указатель на строку, завершаемую null. Приложение может указать этот указатель одним из следующих способов.

Формат строки Description
#dddd Целое число, указанное как десятичная строка. Используется для создания или поиска целочисленного атома.
имя атома строки Строковое имя атома. Используется для добавления строкового имени атома в таблицу atom и получения атома в обратном виде.