Informazioni sulle tabelle Atom
Una tabella atom è una tabella definita dal sistema che archivia stringhe e identificatori corrispondenti. Un'applicazione inserisce una stringa in una tabella atom e riceve un intero a 16 bit, denominato atom, che può essere usato per accedere alla stringa. Una stringa che è stata inserita in una tabella degli atomi è chiamata nome dell'atomo .
Il sistema fornisce una serie di tabelle degli atomi. Ogni tabella degli atomi ha uno scopo diverso. Ad esempio, le applicazioni DDE (Dynamic Data Exchange) usano la tabella atom globale per condividere stringhe nome-elemento e nome di argomento con altre applicazioni. Invece di passare stringhe reali, un'applicazione DDE passa atomi globali all'applicazione partner. Il partner usa gli atomi per ottenere le stringhe dalla tabella degli atomi.
Le applicazioni possono usare tabelle atom locali per archiviare le proprie associazioni di nomi di elemento.
Il sistema usa tabelle atom che non sono direttamente accessibili alle applicazioni. Tuttavia, l'applicazione usa questi atomi quando chiama una varietà di funzioni. Ad esempio, i formati degli appunti registrati sono conservati in una tabella atomica interna usata dal sistema. Un'applicazione aggiunge atomi a questa tabella atom usando la funzione RegisterClipboardFormat. Inoltre, le classi registrate vengono archiviate in una tabella atom interna usata dal sistema. Un'applicazione aggiunge atomi a questa tabella atom usando la funzione RegisterClass o RegisterClassEx.
In questa sezione vengono illustrati gli argomenti seguenti.
- tabella Atom globale
- Tabella utente Atom
- Tabelle Atom locali
- tipi di atomo
- Conteggio di creazione e utilizzo di Atom
- Atom-Table Query
- formati di stringa atom
Tabella Atom globale
La tabella atom globale è disponibile per tutte le applicazioni. Quando un'applicazione inserisce una stringa nella tabella atom globale, il sistema genera un atomo univoco in tutto il sistema. Qualsiasi applicazione che ha l'atom può ottenere la stringa che esso identifica interrogando la tabella globale degli atom.
Un'applicazione che definisce un formato di dati DDE privato per la condivisione di dati con altre applicazioni deve inserire il nome di formato nella tabella atom globale. Questa tecnica impedisce conflitti con i nomi dei formati definiti dal sistema o da altre applicazioni e rende gli identificatori (atom) per i messaggi o i formati disponibili per le altre applicazioni.
Tabella User Atom
Oltre alla tabella globale degli atomi, la tabella degli atomi utente è un'altra tabella degli atomi di sistema condivisa tra tutti i processi. La tabella atom utente viene usata per un numero ridotto di scenari interni a win32k; ad esempio, nomi di moduli di Windows, stringhe note in win32k, formati OLE e così via. Anche se le applicazioni non interagiscono direttamente con la tabella atom dell'utente, chiamano diverse API, ad esempio RegisterClass, RegisterWindowMessagee RegisterClipboardFormat, che aggiungono voci alla tabella atom dell'utente. Gli elementi aggiunti da RegisterClass
possono essere eliminati da UnregisterClass
. Tuttavia, le voci aggiunte da RegisterWindowMessage
e RegisterClipboardFormat
non vengono eliminate fino al termine della sessione. Se la tabella atom dell'utente non ha più spazio e la stringa passata non è già presente nella tabella, la chiamata avrà esito negativo.
Dimensioni tabella Atom
Molte API critiche, tra cui CreateWindow, si basano su atomi utente. Pertanto, l'esaurimento dello spazio nella tabella atom dell'utente causerà gravi problemi; ad esempio, l'avvio di tutte le applicazioni potrebbe non riuscire. Ecco alcuni consigli per garantire che l'applicazione usi tabelle atom in modo efficiente e mantenga l'affidabilità e le prestazioni dell'applicazione e del sistema:
È consigliabile limitare l'utilizzo dell'app della tabella atom dell'utente. L'archiviazione di stringhe univoche tramite API come
RegisterClass
,RegisterWindowMessage
oRegisterClipboardFormat
occupa spazio nella tabella atom dell'utente, usata a livello globale da altre app per registrare classi di finestre usando stringhe. Se possibile, è consigliabile usare AddAtom/DeleteAtom per archiviare le stringhe in una tabella atom locale oppure GlobalAddAtom/GlobalDeleteAtom se sono necessari tra processi.Se ci sono preoccupazioni riguardo ai problemi della tabella atomica degli utenti causati dall'applicazione, è possibile esaminare la causa radice connettendo il debugger del kernel e interrompendo il processo durante le chiamate a
UserAddAtomEx
(bae1 win32kbase!UserAddAtomEx /p <eprocess> "kc10;g"
). Cercareuser32!
nello stack di chiamate per vedere quale API viene chiamata. La metodologia è simile al rilevamento dei problemi nella tabella degli atomi globali, come illustrato in Identificazione delle perdite nella tabella degli atomi globali. Un altro modo per eseguire il dump del contenuto della tabella atom dell'utente consiste nel chiamare GetClipboardFormatName sull'intervallo di atomi possibili da 0xC000 a 0xFFFF. Se il conteggio totale di atomi aumenta costantemente mentre l'applicazione è in esecuzione o non ritorna al valore iniziale quando l'app viene chiusa, c'è un problema.
Tabelle Atom locali
Un'applicazione può usare una tabella atom locale per gestire in modo efficiente un numero elevato di stringhe usate solo all'interno dell'applicazione. Queste stringhe e gli atom associati sono disponibili solo per l'applicazione che ha creato la tabella.
Un'applicazione che richiede la stessa stringa in una serie di strutture può ridurre l'utilizzo della memoria usando una tabella atom locale. Anziché copiare la stringa in ogni struttura, l'applicazione può inserire la stringa nella tabella atom e includere l'atomo risultante nelle strutture. In questo modo, una stringa viene visualizzata una sola volta in memoria, ma può essere usata molte volte nell'applicazione.
Le applicazioni possono anche usare tabelle atom locali per risparmiare tempo durante la ricerca di una determinata stringa. Per eseguire una ricerca, un'applicazione deve inserire solo la stringa di ricerca nella tabella atom e confrontare l'atomo risultante con gli atomi nelle strutture pertinenti. Il confronto degli atomi è in genere più veloce rispetto al confronto delle stringhe.
Le tabelle Atom vengono implementate come tabelle hash. Per impostazione predefinita, una tabella atom locale usa 37 bucket per la tabella hash. Tuttavia, è possibile modificare il numero di bucket usati chiamando la funzione InitAtomTable. Se l'applicazione invoca InitAtomTable, tuttavia, deve farlo prima di invocare qualsiasi altra funzione di gestione degli atomi.
Tipi atom
Le applicazioni possono creare due tipi di atomi: atomi di stringa e atomi interi. I valori degli atomi interi e degli atomi di stringa non si sovrappongono, quindi entrambi i tipi di atomi possono essere usati nello stesso blocco di codice.
Diverse funzioni accettano stringhe o atomi come parametri. Quando si passa un atomo a queste funzioni, un'applicazione può utilizzare la macro MAKEINTATOM per convertire l'atomo in una forma che può essere usata dalla funzione.
Le sezioni seguenti descrivono i tipi di atomi.
Atomi di stringa
Quando le applicazioni passano stringhe con terminazione Null alle funzioni diGlobalAddAtom, AddAtom, GlobalFindAtome FindAtom, ricevono atomi di stringa (numeri interi a 16 bit) restituiti. Gli atomi di stringa hanno le proprietà seguenti:
- I valori degli atomi di stringa sono compresi nell'intervallo da 0xC000 (MAXINTATOM) fino a 0xFFFF.
- La distinzione tra maiuscole e minuscole non è significativa nelle ricerche di un nome di atomo in una tabella degli atomi. Inoltre, l'intera stringa deve corrispondere in un'operazione di ricerca; non viene eseguita alcuna corrispondenza di sottostringa.
- La stringa associata a un atomo di stringa non può essere maggiore di 255 byte. Questa limitazione si applica a tutte le funzioni atom.
- Un conteggio dei riferimenti è associato a ogni nome dell'atomo. Il conteggio viene incrementato ogni volta che il nome atomo viene aggiunto alla tabella e decrementato ogni volta che il nome dell'atomo viene eliminato. Ciò impedisce agli utenti diversi dello stesso atomo di stringhe di eliminare i nomi degli atomi degli altri. Quando il conteggio dei riferimenti per un nome atom è uguale a zero, il sistema rimuove l'atomo e il nome dell'atomo dalla tabella.
Atomi interi
Gli atomi interi differiscono dagli atomi di stringa nei modi seguenti:
- I valori degli atomi interi sono compresi nell'intervallo 0x0001 da 0xBFFF (MAXINTATOM- 1).
- La rappresentazione di stringa di un atomo intero è #dddd, dove i valori rappresentati da dddd sono cifre decimali. Gli zeri iniziali vengono ignorati.
- Nessun conteggio dei riferimenti o sovraccarico di archiviazione associato a un atomo intero.
Creazione e conteggio dell'utilizzo degli atomi
Un'applicazione crea un atomo locale chiamando la funzioneaddAtom; crea un atomo globale chiamando la funzioneglobalAddAtom. Entrambe le funzioni richiedono un puntatore a una stringa. Il sistema cerca nella tabella atom appropriata la stringa e restituisce l'atom corrispondente all'applicazione. Nel caso di un atomo di stringa, se la stringa risiede già nella tabella atom, il sistema incrementa il conteggio dei riferimenti per la stringa durante questo processo.
Le chiamate ripetute per aggiungere lo stesso nome di atomo restituiscono lo stesso atomo. Se il nome atom non esiste nella tabella quando viene chiamato addAtom, il nome atom viene aggiunto alla tabella e viene restituito un nuovo atomo. Se si tratta di un atomo di stringa, anche il conteggio dei riferimenti viene impostato su uno.
Un'applicazione deve chiamare la funzionedeleteAtomquando non deve più usare un atomo locale; deve chiamare la funzione GlobalDeleteAtom quando non ha più bisogno di un atomo globale. Nel caso di un atomo di stringa, una di queste funzioni riduce il numero di riferimenti dell'atomo corrispondente di uno. Quando il conteggio dei riferimenti raggiunge zero, il sistema elimina il nome atomo dalla tabella.
Il nome di un atomo di stringa rimane nella tabella globale degli atomi finché il conteggio dei riferimenti è maggiore di zero, anche dopo la chiusura dell'applicazione che l'ha inserito nella tabella. Una tabella atom locale viene eliminata definitivamente quando l'applicazione associata termina, indipendentemente dal numero di riferimenti degli atomi nella tabella.
query Atom-Table
Un'applicazione può determinare se una determinata stringa è già presente in una tabella atom usando la funzioneFindAtomo GlobalFindAtom. Queste funzioni cercano una tabella atom per la stringa specificata e, se la stringa è presente, restituiscono l'atom corrispondente.
Un'applicazione può usare la funzioneGetAtomNameo GlobalGetAtomName per recuperare una stringa di nome atom da una tabella atom, a condizione che l'applicazione abbia l'atom corrispondente alla stringa ricercata. Entrambe le funzioni copiano la stringa atom-name dell'atom specificato in un buffer e restituiscono la lunghezza della stringa copiata. GetAtomName recupera una stringa atom-name da una tabella atom locale e GlobalGetAtomName recupera una stringa atom-name dalla tabella atom globale.
Formati di stringa Atom
Le funzioniAddAtomGlobalAddAtom, FindAtome GlobalFindAtom accettano un puntatore a una stringa con terminazione Null. Un'applicazione può specificare questo puntatore in uno dei modi seguenti.
Formato stringa | Descrizione |
---|---|
# dddd | Intero specificato come stringa decimale. Usato per creare o trovare un atomo intero. |
nome atomo stringa | Nome di atomo di stringa. Usato per aggiungere un nome dell'atomo di stringa a una tabella degli atomi e ricevere un atomo in ritorno. |