Partilhar via


Sobre as tabelas Atom

Uma tabela de átomos é uma tabela definida pelo sistema que armazena cadeias de caracteres e identificadores correspondentes. Uma aplicação coloca uma cadeia de caracteres numa tabela de átomos e recebe um inteiro de 16 bits, chamado de átomo , que pode ser usado para acessar a cadeia de caracteres. Uma cadeia de caracteres que foi colocada em uma tabela de átomos é chamada de nome de átomo .

O sistema fornece uma série de tabelas de átomos. Cada tabela de átomos serve a um propósito diferente. Por exemplo, as aplicações de Troca Dinâmica de Dados (DDE) usam a tabela global de átomos para compartilhar as cadeias de nomes de itens e tópicos com outras aplicações. Em vez de passar cadeias de caracteres reais, um aplicativo DDE passa átomos globais para seu aplicativo parceiro. O parceiro usa os átomos para obter as cadeias da tabela de átomos.

Os aplicativos podem usar tabelas de átomos locais para armazenar suas próprias associações de nome de item.

O sistema usa tabelas atom que não são diretamente acessíveis aos aplicativos. No entanto, o aplicativo usa esses átomos ao chamar uma variedade de funções. Por exemplo, os formatos registrados da área de transferência são armazenados em uma tabela de átomos interna usada pelo sistema. Um aplicativo adiciona átomos a essa tabela de átomos usando a funçãoRegisterClipboardFormat. Além disso, as classes registradas são armazenadas em uma tabela de átomos interna usada pelo sistema. Um aplicativo adiciona átomos a esta tabela de átomos usando a função RegisterClass ou a função RegisterClassEx.

Os tópicos a seguir são discutidos nesta seção.

Tabela Global Atom

A tabela global de átomos está disponível para todas as aplicações. Quando um aplicativo coloca uma cadeia de caracteres na tabela global de átomos, o sistema gera um átomo que é exclusivo em todo o sistema. Qualquer aplicativo que tenha o átomo pode obter a cadeia de caracteres que ele identifica consultando a tabela global de átomos.

Um aplicativo que define um formato de dados DDE privado para compartilhar dados com outros aplicativos deve colocar o nome do formato na tabela global atom. Esta técnica evita conflitos com os nomes dos formatos definidos pelo sistema ou por outras aplicações, e disponibiliza os identificadores (átomos) das mensagens ou formatos para as outras aplicações.

Tabela Atom do Usuário

Além da tabela de átomos global, a tabela de átomos do usuário é outra tabela de átomos do sistema que também é compartilhada em todos os processos. A tabela atom do usuário é usada para um pequeno número de cenários internos ao win32k; por exemplo, nomes de módulos do Windows, cadeias de caracteres bem conhecidas no win32k, formatos OLE, etc. Embora os aplicativos não interajam diretamente com a tabela atom do usuário, eles chamam várias APIs — como RegisterClass, RegisterWindowMessagee RegisterClipboardFormat— que adicionam entradas à tabela atom do usuário. As entradas adicionadas por RegisterClass podem ser excluídas por UnregisterClass. No entanto, as entradas adicionadas por RegisterWindowMessage e RegisterClipboardFormat não são excluídas até que a sessão termine. Se a tabela atom do usuário não tiver mais espaço e a cadeia de caracteres que está sendo passada ainda não estiver na tabela, a chamada falhará.

Tamanho da tabela de átomos

Muitas APIs críticas, incluindo CreateWindow, dependem de átomos de usuário. Portanto, a exaustão do espaço na tabela de átomos do usuário resultará em problemas sérios; Por exemplo, todos os aplicativos podem falhar ao iniciar. Aqui estão algumas recomendações para garantir que seu aplicativo utilize tabelas atom de forma eficiente e preserve a confiabilidade e o desempenho do aplicativo e do sistema:

  1. Deve limitar o uso da tabela de átomos do utilizador pela sua aplicação. O armazenamento de cadeias de caracteres exclusivas usando APIs como RegisterClass, RegisterWindowMessageou RegisterClipboardFormat ocupa espaço na tabela atom do usuário, que é usada globalmente por outros aplicativos para registrar classes de janela usando cadeias de caracteres. Se possível, deverá usar AddAtom /DeleteAtom para armazenar cadeias de caracteres numa tabela de átomos local, ou GlobalAddAtom /GlobalDeleteAtom se os átomos forem necessários entre processos.

  2. Se houver preocupação com o aplicativo causando problemas na tabela atom do usuário, pode investigar a causa raiz conectando o depurador do kernel e interrompendo o processo nas chamadas para UserAddAtomEx (bae1 win32kbase!UserAddAtomEx /p <eprocess> "kc10;g"). Procure user32! na pilha de chamadas para verificar qual é a API a ser chamada. A metodologia é semelhante à deteção de problemas da tabela global de átomos explicada em Identifying Global Atom Table Leaks. Outra maneira de esvaziar o conteúdo da Tabela de Átomos do Utilizador é chamando GetClipboardFormatName no intervalo de possíveis átomos de 0xC000 a 0xFFFF. Se a contagem total de átomos aumentar constantemente enquanto o aplicativo está em execução ou não retornar à linha de base quando o aplicativo for fechado, há um problema.

Tabelas Atom Locais

Um aplicativo pode usar uma tabela atom local para gerenciar eficientemente um grande número de cadeias de caracteres usadas apenas dentro do aplicativo. Essas cadeias de caracteres e os átomos associados estão disponíveis apenas para o aplicativo que criou a tabela.

Um aplicativo que requer a mesma cadeia de caracteres em várias estruturas pode reduzir o uso de memória usando uma tabela de átomos local. Em vez de copiar a string em cada estrutura, o aplicativo pode colocar a string na tabela de átomos e incluir o átomo resultante nas estruturas. Desta forma, uma string aparece apenas uma vez na memória, mas pode ser usada muitas vezes no aplicativo.

Os aplicativos também podem usar tabelas atom locais para economizar tempo ao procurar uma cadeia de caracteres específica. Para realizar uma pesquisa, um aplicativo só precisa colocar a cadeia de pesquisa na tabela de átomos e comparar o átomo resultante com os átomos nas estruturas relevantes. Comparar átomos é normalmente mais rápido do que comparar cadeias de caracteres.

As tabelas Atom são implementadas como tabelas de hash. Por padrão, uma tabela atom local usa 37 buckets para sua tabela de hash. No entanto, você pode alterar o número de buckets usados chamando a funçãoInitAtomTable. Se o aplicativo chamar InitAtomTable, no entanto, ele deve fazê-lo antes de chamar quaisquer outras funções de gerenciamento de átomos.

Tipos de átomos

As aplicações podem criar dois tipos de átomos: átomos de cadeia e átomos inteiros. Os valores de átomos inteiros e átomos de cadeia não se sobrepõem, portanto, ambos os tipos de átomos podem ser usados no mesmo bloco de código.

Várias funções aceitam cadeias de caracteres ou átomos como parâmetros. Ao passar um átomo para essas funções, um aplicativo pode usar o macro MAKEINTATOM para converter o átomo em uma forma que pode ser usada pela função.

As seções a seguir descrevem os tipos de átomos.

Átomos de corda

Quando os aplicativos passam cadeias de caracteres terminadas em nulo para o GlobalAddAtom, AddAtom, GlobalFindAtome funções de FindAtom, eles recebem de cadeia de caracteres (inteiros de 16 bits) em troca. Os átomos de cadeia têm as seguintes propriedades:

  • Os valores dos átomos string estão no intervalo 0xC000 (MAXINTATOM) até 0xFFFF.
  • O caso não é significativo nas pesquisas por um nome de átomo em uma tabela de átomos. Além disso, toda a cadeia de caracteres deve corresponder em uma operação de pesquisa; nenhuma correspondência de substring é executada.
  • A cadeia de caracteres associada a um átomo de cadeia de caracteres não pode ter mais de 255 bytes de tamanho. Esta limitação aplica-se a todas as funções do átomo.
  • Uma contagem de referência está associada a cada nome de átomo. A contagem é incrementada cada vez que o nome do átomo é adicionado à tabela e diminuída cada vez que o nome do átomo é excluído dela. Isso impede que diferentes usuários do mesmo átomo de cadeia destruam os nomes de átomos uns dos outros. Quando a contagem de referência para um nome de átomo é igual a zero, o sistema remove o átomo e o nome do átomo da tabela.

Átomos inteiros

Os átomos inteiros diferem dos átomos de cadeia das seguintes maneiras:

  • Os valores dos átomos inteiros estão no intervalo 0x0001 até 0xBFFF (MAXINTATOM– 1).
  • A representação de cadeia de caracteres de um átomo inteiro é #dddd, onde os valores representados por dddd são dígitos decimais. Os zeros à esquerda são ignorados.
  • Não há contagem de referência ou sobrecarga de armazenamento associada a um átomo inteiro.

Criação de átomos e contagem de uso

Um aplicativo cria um átomo local chamando a função AddAtom; ele cria um átomo global chamando a função GlobalAddAtom. Ambas as funções requerem um ponteiro para uma cadeia de caracteres. O sistema procura a cadeia de caracteres na tabela de átomos apropriada e retorna o átomo correspondente ao aplicativo. No caso de um átomo de cadeia de caracteres, se a cadeia de caracteres já reside na tabela de átomos, o sistema incrementa a contagem de referência para a cadeia de caracteres durante esse processo.

Chamadas repetidas para adicionar o mesmo nome de átomo retornam o mesmo átomo. Se o nome do átomo não existir na tabela quando AddAtom for chamado, o nome do átomo será adicionado à tabela e um novo átomo será retornado. Se for um átomo de cadeia de caracteres, sua contagem de referência também será definida como um.

Um aplicativo deve chamar a funçãoDeleteAtom quando não precisar mais usar um átomo local; ele deve chamar a funçãoGlobalDeleteAtom quando não precisar mais de um átomo global. No caso de um átomo de cadeia, qualquer uma dessas funções reduz a contagem de referência do átomo correspondente em um. Quando a contagem de referência atinge zero, o sistema exclui o nome do átomo da tabela.

O nome do átomo de uma cadeia de caracteres permanece na tabela global de átomos enquanto sua contagem de referência for maior que zero, mesmo após o término do aplicativo que o colocou na tabela. Uma tabela de átomos local é destruída quando o aplicativo associado termina, independentemente das contagens de referência dos átomos na tabela.

Atom-Table Consultas

Um aplicativo pode determinar se uma cadeia de caracteres específica já está em uma tabela atom usando o FindAtom ou função GlobalFindAtom. Essas funções pesquisam uma tabela de átomos para a string especificada e, se a string estiver lá, retornam o átomo correspondente.

Um aplicativo pode usar o GetAtomName ou função GlobalGetAtomName para recuperar uma cadeia de caracteres de nome de átomo de uma tabela de átomos, desde que o aplicativo tenha o átomo correspondente à cadeia de caracteres que está sendo procurada. Ambas as funções copiam a cadeia de caracteres de nome de átomo do átomo especificado para um buffer e retornam o comprimento da cadeia de caracteres que foi copiada. GetAtomName recupera uma cadeia de caracteres do nome do átomo de uma tabela de átomos local e GlobalGetAtomName recupera uma cadeia de caracteres do nome do átomo da tabela de átomos global.

Formatos Atom String

As funções AddAtom, GlobalAddAtom, FindAtome GlobalFindAtom recebem um ponteiro para uma cadeia de caracteres terminada em nulo. Um aplicativo pode especificar esse ponteiro de uma das seguintes maneiras.

Formato da cadeia de caracteres Descrição
# dddd Um inteiro especificado como uma cadeia decimal. Usado para criar ou encontrar um átomo inteiro.
nome do átomo de cadeia de caracteres Nome de um átomo do tipo string. Usado para adicionar um nome de átomo de cadeia de caracteres a uma tabela de átomos e receber um átomo em troca.