Informationen zu Atom-Tabellen
Eine Atomtabelle ist eine systemdefinierte Tabelle, in der Zeichenfolgen und entsprechende Bezeichner gespeichert werden. Eine Anwendung platziert eine Zeichenfolge in einer Atomtabelle und empfängt eine 16-Bit-Ganzzahl, die als atom bezeichnet wird und für den Zugriff auf die Zeichenfolge verwendet werden kann. Eine Zeichenfolge, die in einer Atomtabelle platziert wurde, wird als Atomname bezeichnet.
Das System stellt eine Reihe von Atomtabellen bereit. Jede Atomtabelle dient einem anderen Zweck. Beispielsweise verwenden dynamische Daten Exchange -Anwendungen (DDE) die globale Atomtabelle, um Elementnamen- und Themennamenzeichenfolgen für andere Anwendungen freizugeben. Anstatt tatsächliche Zeichenfolgen zu übergeben, übergibt eine DDE-Anwendung globale Atome an ihre Partneranwendung. Der Partner verwendet die Atome, um die Zeichenfolgen aus der Atomtabelle abzurufen.
Anwendungen können lokale Atomtabellen verwenden, um ihre eigenen Elementnamenzuordnungen zu speichern.
Das System verwendet Atomtabellen, auf die Anwendungen nicht direkt zugreifen können. Die Anwendung verwendet diese Atome jedoch beim Aufrufen einer Vielzahl von Funktionen. Registrierte Zwischenablageformate werden beispielsweise in einer internen Atomtabelle gespeichert, die vom System verwendet wird. Eine Anwendung fügt atoms mithilfe der RegisterClipboardFormat-Funktion zu dieser Atomtabelle hinzu. Außerdem werden registrierte Klassen in einer internen Atomtabelle gespeichert, die vom System verwendet wird. Eine Anwendung fügt atoms mithilfe der RegisterClass- oder RegisterClassEx-Funktion zu dieser Atomtabelle hinzu.
Die folgenden Themen werden in diesem Abschnitt erläutert.
- Global Atom-Tabelle
- User Atom-Tabelle
- Lokale Atomtabellen
- Atom-Typen
- Atom-Erstellung und -Nutzungsanzahl
- Atom-Table-Abfragen
- Atom-Zeichenfolgenformate
Global Atom-Tabelle
Die globale Atomtabelle ist für alle Anwendungen verfügbar. Wenn eine Anwendung eine Zeichenfolge in der globalen Atomtabelle platziert, generiert das System ein Atom, das im gesamten System eindeutig ist. Jede Anwendung mit dem Atom kann die von ihr identifizierte Zeichenfolge abrufen, indem sie die globale Atomtabelle abfragt.
Eine Anwendung, die ein privates DDE-Datenformat für die Freigabe von Daten für andere Anwendungen definiert, sollte den Formatnamen in der globalen Atomtabelle platzieren. Diese Technik verhindert Konflikte mit den Namen von Formaten, die vom System oder von anderen Anwendungen definiert werden, und macht die Bezeichner (Atome) für die Nachrichten oder Formate für die anderen Anwendungen verfügbar.
User Atom-Tabelle
Zusätzlich zur globalen Atomtabelle ist die Benutzer-Atomtabelle eine weitere Atomtabelle des Systems, die auch für alle Prozesse freigegeben ist. Die Benutzer-Atomtabelle wird für eine kleine Anzahl von internen Szenarien für win32k verwendet. Beispielsweise Windows-Modulnamen, bekannte Zeichenfolgen in win32k, OLE-Formaten usw. Obwohl Anwendungen nicht direkt mit der Atomtabelle des Benutzers interagieren, rufen sie mehrere APIs wie RegisterClass, RegisterWindowMessageund RegisterClipboardFormatauf, die der Atomtabelle des Benutzers Einträge hinzufügen. Die von hinzugefügten Einträge RegisterClass können von gelöscht UnregisterClass werden. Die von und hinzugefügten Einträge werden jedoch RegisterWindowMessage RegisterClipboardFormat erst gelöscht, nachdem die Sitzung beendet wurde. Wenn die Benutzer-Atomtabelle keinen Speicherplatz mehr hat und die übergebene Zeichenfolge nicht bereits in der Tabelle enthalten ist, schlägt der Aufruf fehl.
Atom-Tabellengröße
Viele wichtige APIs, einschließlich CreateWindow,basieren auf Benutzer-Atomen. Daher führt die Speicherplatzausschöpfung in der Benutzer-Atomtabelle zu schwerwiegenden Problemen. Beispielsweise können alle Anwendungen möglicherweise nicht gestartet werden. Im Folgenden finden Sie einige Empfehlungen, um sicherzustellen, dass Ihre Anwendung Atomtabellen effizient nutzt und die Zuverlässigkeit und Leistung der Anwendung und des Systems gewährleistet:
Sie sollten die Nutzung der Benutzer-Atomtabelle durch Ihre App einschränken. Das Speichern eindeutiger Zeichenfolgen mitHILFE von APIs wie
RegisterClass, oder nimmt Speicherplatz in derRegisterWindowMessageRegisterClipboardFormatAtomtabelle des Benutzers ein, die global von anderen Apps verwendet wird, um Fensterklassen mithilfe von Zeichenfolgen zu registrieren. Wenn möglich, sollten Sie AddAtomDeleteAtom verwenden, / um Zeichenfolgen in einer lokalen Atomtabelle zu speichern, oder GlobalAddAtom / GlobalDeleteAtom, wenn die Atome prozessübergreifend benötigt werden.Wenn bedenken, dass die Anwendung Probleme mit der Atomtabelle des Benutzers verursacht, können Sie die Grundursache untersuchen, indem Sie den Kerneldebugger verbinden und bei Aufrufen von ( ) in den Prozess
UserAddAtomExbae1 win32kbase!UserAddAtomEx /p <eprocess> "kc10;g"einbrechen. Suchen Sieuser32!in der Aufrufstapel nach , um zu sehen, welche API aufgerufen wird. Die Methodik ähnelt der Problemerkennung bei globalen Atomtabellen, die unter Identifying Global Atom Table Leaks (Identifizieren von globalen Atomtabellenverlusten)erläutert wird. Eine weitere Möglichkeit, den Inhalt der Benutzer-Atomtabelle zu speichern, besteht darin, GetClipboardFormatName über den Bereich möglicher Atome von 0xC000 bis 0xFFFF aufzurufen. Wenn die Gesamtanzahl der Atome stetig steigt, während die Anwendung ausgeführt wird, oder nicht zur Baseline zurückkehrt, wenn die App geschlossen wird, liegt ein Problem vor.
Lokale Atomtabellen
Eine Anwendung kann eine lokale Atomtabelle verwenden, um eine große Anzahl von Zeichenfolgen effizient zu verwalten, die nur innerhalb der Anwendung verwendet werden. Diese Zeichenfolgen und die zugeordneten Atome sind nur für die Anwendung verfügbar, die die Tabelle erstellt hat.
Eine Anwendung, die dieselbe Zeichenfolge in einer Reihe von Strukturen erfordert, kann die Speicherauslastung mithilfe einer lokalen Atomtabelle reduzieren. Anstatt die Zeichenfolge in jede Struktur zu kopieren, kann die Anwendung die Zeichenfolge in der Atomtabelle platzieren und das resultierende Atom in die Strukturen einschließen. Auf diese Weise wird eine Zeichenfolge nur einmal im Arbeitsspeicher angezeigt, kann aber mehrmals in der Anwendung verwendet werden.
Anwendungen können auch lokale Atomtabellen verwenden, um Zeit bei der Suche nach einer bestimmten Zeichenfolge zu sparen. Um eine Suche durchzuführen, muss eine Anwendung nur die Suchzeichenfolge in der Atomtabelle platzieren und das resultierende Atom mit den Atomen in den relevanten Strukturen vergleichen. Der Vergleich von Atomen ist in der Regel schneller als das Vergleichen von Zeichenfolgen.
Atom-Tabellen werden als Hashtabellen implementiert. Standardmäßig verwendet eine lokale Atomtabelle 37 Buckets für ihre Hashtabelle. Sie können jedoch die Anzahl der verwendeten Buckets ändern, indem Sie die InitAtomTable-Funktion aufrufen. Wenn die Anwendung InitAtomTable aufruft, muss sie dies jedoch tun, bevor andere Atomverwaltungsfunktionen aufgerufen werden.
Atom-Typen
Anwendungen können zwei Typen von Atomen erstellen: Zeichenfolgen-Atome und ganzzahlige Atome. Die Werte von ganzzahligen Atomen und Zeichenfolgen-Atomen überlappen sich nicht, sodass beide Atomtypen im gleichen Codeblock verwendet werden können.
Mehrere Funktionen akzeptieren Zeichenfolgen oder Atome als Parameter. Wenn ein Atom an diese Funktionen übergeben wird, kann eine Anwendung das MAKEINTATOM-Makro verwenden, um das Atom in eine Form zu konvertieren, die von der Funktion verwendet werden kann.
In den folgenden Abschnitten werden Atomtypen beschrieben.
Zeichenfolgen-Atome
Wenn Anwendungen NULL-endende Zeichenfolgen an die Funktionen GlobalAddAtom, AddAtom, GlobalFindAtomund FindAtom übergeben, erhalten sie zeichenfolgenbasierte Atome (16-Bit-Ganzzahlen) als Rückgabe. Zeichenfolgen-Atome haben die folgenden Eigenschaften:
- Die Werte von Zeichenfolgen-Atomen liegen im Bereich 0xC000 (MAXINTATOM) bis 0xFFFF.
- Die Groß-/Schreibung ist bei der Suche nach einem Atomnamen in einer Atomtabelle nicht von Bedeutung. Außerdem muss die gesamte Zeichenfolge in einem Suchvorgang übereinstimmen. Es wird kein Abgleich der Teilzeichenfolge durchgeführt.
- Die einem Zeichenfolgen-Atom zugeordnete Zeichenfolge darf maximal 255 Bytes groß sein. Diese Einschränkung gilt für alle Atomfunktionen.
- Jedem Atomnamen ist ein Verweiszähler zugeordnet. Die Anzahl wird jedes Mal erhöht, wenn der Atomname der Tabelle hinzugefügt und bei jedem Löschen des Atomnamens dekrementiert wird. Dadurch wird verhindert, dass verschiedene Benutzer desselben Zeichenfolgen-Atoms die Atomnamen des jeweils anderen zerstören. Wenn der Verweiszähler für einen Atomnamen gleich 0 (null) ist, entfernt das System das Atom und den Atomnamen aus der Tabelle.
Ganzzahlige Atome
Ganzzahlige Atome unterscheiden sich wie folgt von Zeichenfolgen-Atomen:
- Die Werte ganzzahliger Atome liegen im Bereich 0x0001 bis 0xBFFF (MAXINTATOM– 1).
- Die Zeichenfolgendarstellung eines ganzzahligen Atoms ist # dddd, wobei die durch dddd dargestellten Werte Dezimalziffern sind. Führende Nullen werden ignoriert.
- Einem ganzzahligen Atom ist kein Verweiszähler oder Speicheraufwand zugeordnet.
Atomerstellung und Nutzungsanzahl
Eine Anwendung erstellt ein lokales Atom, indem die AddAtom-Funktion aufgerufen wird. es erstellt ein globales Atom, indem die GlobalAddAtom-Funktion aufgerufen wird. Beide Funktionen erfordern einen Zeiger auf eine Zeichenfolge. Das System durchsucht die entsprechende Atomtabelle nach der Zeichenfolge und gibt das entsprechende Atom an die Anwendung zurück. Wenn sich die Zeichenfolge im Fall eines Zeichenfolgen-Atoms bereits in der Atomtabelle befindet, erhöht das System während dieses Prozesses den Verweiszähler für die Zeichenfolge.
Wiederholte Aufrufe zum Hinzufügen des gleichen Atomnamens geben das gleiche Atom zurück. Wenn der Atomname in der Tabelle nicht vorhanden ist, wenn AddAtom aufgerufen wird, wird der Atomname der Tabelle hinzugefügt, und ein neues Atom wird zurückgegeben. Wenn es sich um ein Zeichenfolgen-Atom handelt, wird auch der Verweiszähler auf 1 festgelegt.
Eine Anwendung sollte die DeleteAtom-Funktion aufrufen, wenn sie kein lokales Atom mehr verwenden muss. sie sollte die GlobalDeleteAtom-Funktion aufrufen, wenn sie kein globales Atom mehr benötigt. Im Fall eines Zeichenfolgen-Atoms verringert eine dieser Funktionen den Verweiszähler des entsprechenden Atoms um eins. Wenn der Verweiszähler 0 (null) erreicht, löscht das System den Atomnamen aus der Tabelle.
Der Atomname eines Zeichenfolgen-Atoms verbleibt in der globalen Atomtabelle, solange der Verweiszähler größer als 0 (null) ist, auch wenn die Anwendung, die es in der Tabelle platziert hat, beendet wird. Eine lokale Atomtabelle wird zerstört, wenn die zugeordnete Anwendung beendet wird, unabhängig von der Verweisanzahl der Atome in der Tabelle.
Atom-Table Abfragen
Eine Anwendung kann mithilfe der Funktion FindAtom oder GlobalFindAtom bestimmen, ob sich eine bestimmte Zeichenfolge bereits in einer Atomtabelle befindet. Diese Funktionen durchsuchen eine Atomtabelle nach der angegebenen Zeichenfolge und geben das entsprechende Atom zurück, wenn die Zeichenfolge vorhanden ist.
Eine Anwendung kann die Funktion GetAtomName oder GlobalGetAtomName verwenden, um eine Atomnamenzeichenfolge aus einer Atomtabelle abzurufen, vorausgesetzt, die Anwendung verfügt über das Atom, das der gesuchten Zeichenfolge entspricht. Beide Funktionen kopieren die Atomnamenzeichenfolge des angegebenen Atoms in einen Puffer und geben die Länge der kopierten Zeichenfolge zurück. GetAtomName ruft eine Atomnamenzeichenfolge aus einer lokalen Atomtabelle ab, und GlobalGetAtomName ruft eine Atomnamenzeichenfolge aus der globalen Atomtabelle ab.
Atom-Zeichenfolgenformate
Die Funktionen AddAtom, GlobalAddAtom, FindAtomund GlobalFindAtom verwenden einen Zeiger auf eine auf NULL endende Zeichenfolge. Eine Anwendung kann diesen Zeiger auf eine der folgenden Arten angeben.
| Zeichenfolgenformat | BESCHREIBUNG |
|---|---|
| #Dddd | Eine ganze Zahl, die als Dezimalzeichenfolge angegeben ist. Wird zum Erstellen oder Suchen eines ganzzahligen Atoms verwendet. |
| Zeichenfolgen-Atomname | Ein Zeichenfolgen-Atomname. Wird verwendet, um einer Atomtabelle einen Zeichenfolgen-Atomnamen hinzuzufügen und als Rückgabe ein Atom zu empfangen. |