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 DDE-Anwendungen (Dynamic Data Exchange) die globale Atomtabelle , um Elementnamen- und Themennamenzeichenfolgen für andere Anwendungen gemeinsam zu nutzen. 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. Beispielsweise werden registrierte Zwischenablageformate in einer internen Atomtabelle gespeichert, die vom System verwendet wird. Eine Anwendung fügt dieser Atomtabelle mithilfe der Funktion RegisterClipboardFormat Atome hinzu. Außerdem werden registrierte Klassen in einer internen Atomtabelle gespeichert, die vom System verwendet wird. Eine Anwendung fügt dieser Atomtabelle Atome mithilfe der RegisterClass- oder RegisterClassEx-Funktion hinzu.

Die folgenden Themen werden in diesem Abschnitt behandelt.

Globale Atomtabelle

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 identifizierte Zeichenfolge abrufen, indem die globale Atomtabelle abgefragt wird.

Eine Anwendung, die ein privates DDE-Datenformat für die Freigabe von Daten mit anderen 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 stellt die Bezeichner (Atome) für die Nachrichten oder Formate den anderen Anwendungen zur Verfügung.

Atom-Tabelle für Benutzer

Neben der globalen Atomtabelle ist die Benutzeratomtabelle eine weitere Systematomtabelle, die auch für alle Prozesse gemeinsam genutzt wird. Die Benutzer-Atomtabelle wird für eine kleine Anzahl von Szenarien verwendet, die intern für win32k verwendet werden. Beispielsweise Windows-Modulnamen, bekannte Zeichenfolgen in Win32k, OLE-Formate usw. Obwohl Anwendungen nicht direkt mit der Atomtabelle des Benutzers interagieren, rufen sie mehrere APIs wie RegisterClass, RegisterWindowMessage und RegisterClipboardFormat auf, die der Atomtabelle des Benutzers Einträge hinzufügen. Die von RegisterClass hinzugefügten Einträge können von gelöscht werden UnregisterClass. Die Einträge, die von und hinzugefügt wurden RegisterWindowMessageRegisterClipboardFormat , werden jedoch erst gelöscht, wenn die Sitzung endet. Wenn die Atomtabelle des Benutzers keinen Speicherplatz mehr hat und die übergebene Zeichenfolge noch nicht in der Tabelle enthalten ist, schlägt der Aufruf fehl.

Atom-Tabellengröße

Viele kritische APIs, einschließlich CreateWindow, basieren auf Benutzeratomen. Daher führt die Raumauslastung in der Atomtabelle des Benutzers zu ernsthaften Problemen; Beispielsweise können alle Anwendungen möglicherweise nicht gestartet werden. Hier finden Sie einige Empfehlungen, um sicherzustellen, dass Ihre Anwendung Atomtabellen effizient nutzt und die Zuverlässigkeit und Leistung der Anwendung und des Systems bewahrt:

  1. Sie sollten die Verwendung der Benutzer-Atomtabelle in Ihrer App einschränken. Das Speichern eindeutiger Zeichenfolgen mithilfe von APIs wie RegisterClass, RegisterWindowMessageoder RegisterClipboardFormat nimmt Platz in der Atomtabelle des Benutzers ein, die global von anderen Apps verwendet wird, um Fensterklassen mithilfe von Zeichenfolgen zu registrieren. Wenn möglich, sollten Sie AddAtom/DeleteAtom verwenden, um Zeichenfolgen in einer lokalen Atomtabelle zu speichern, oder GlobalAddAtom/GlobalDeleteAtom , wenn die Atome prozessübergreifend benötigt werden.

  2. Wenn Bedenken bestehen, dass die Anwendung Probleme mit der Atomtabelle für Benutzer verursacht, können Sie die Grundursache untersuchen, indem Sie den Kerneldebugger verbinden und bei Aufrufen UserAddAtomEx von (bae1 win32kbase!UserAddAtomEx /p <eprocess> "kc10;g") in den Prozess einbrechen. user32! Suchen Sie in der Aufrufliste nach, um zu sehen, welche API aufgerufen wird. Die Methodik ähnelt der Erkennung globaler Atomtabellen-Probleme, die unter Identifizieren globaler Atomtabellenlecks erläutert wird. Eine weitere Möglichkeit, den Inhalt der Benutzer-Atomtabelle abzuspeichern, besteht darin , GetClipboardFormatName über den Bereich möglicher Atome von 0xC000 bis 0xFFFF aufzurufen. Wenn die Gesamtzahl der Atome während der Ausführung der Anwendung kontinuierlich steigt oder beim Schließen der App nicht zur Baseline zurückkehrt, 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 durch die Verwendung 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 in der Anwendung mehrfach 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 der Vergleich von Zeichenfolgen.

Atom-Tabellen werden als Hashtabellen implementiert. Standardmäßig verwendet eine lokale Atomtabelle 37 Buckets für die Hashtabelle. Sie können jedoch die Anzahl der verwendeten Buckets ändern, indem Sie die InitAtomTable-Funktion aufrufen. Wenn die Anwendung jedoch InitAtomTable aufruft, muss sie dies tun, bevor sie andere Atomverwaltungsfunktionen aufruft.

Atomtypen

Anwendungen können zwei Atomtypen erstellen: Zeichenfolgenatome und ganzzahlige Atome. Die Werte von ganzzahligen Atomen und Zeichenfolgenatomen überlappen sich nicht, sodass beide Atomtypen im selben Codeblock verwendet werden können.

Mehrere Funktionen akzeptieren entweder 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.

Zeichenfolgenatome

Wenn Anwendungen NULL-terminierte Zeichenfolgen an die Funktionen GlobalAddAtom, AddAtom, GlobalFindAtom und FindAtom übergeben, erhalten sie Zeichenfolgenatome (16-Bit-Ganzzahlen) im Gegenzug. Zeichenfolgenatome haben die folgenden Eigenschaften:

  • Die Werte von Zeichenfolgenatomen liegen im Bereich 0xC000 (MAXINTATOM) bis 0xFFFF.
  • Die Groß-/Kleinschreibung ist bei der Suche nach einem Atomnamen in einer Atomtabelle nicht signifikant. Außerdem muss die gesamte Zeichenfolge in einem Suchvorgang übereinstimmen. es wird kein Teilzeichenfolgenabgleich durchgeführt.
  • Die einem Zeichenfolgenatom zugeordnete Zeichenfolge darf nicht mehr als 255 Byte groß sein. Diese Einschränkung gilt für alle Atomfunktionen.
  • Jedem Atomnamen ist eine Verweisanzahl zugeordnet. Die Anzahl wird jedes Mal erhöht, wenn der Atomname der Tabelle hinzugefügt und bei jedem Löschen des Atomnamens verringert wird. Dadurch wird verhindert, dass verschiedene Benutzer desselben Zeichenfolgenatoms die Atomnamen des anderen zerstören. Wenn die Verweisanzahl für einen Atomnamen gleich 0 ist, entfernt das System das Atom und den Atomnamen aus der Tabelle.

Ganzzahlige Atome

Ganzzahlige Atome unterscheiden sich auf folgende Weise von Zeichenfolgenatomen:

  • Die Werte ganzzahliger Atome liegen im Bereich 0x0001 bis 0xBFFF (MAXINTATOM– 1).
  • Die Zeichenfolgendarstellung eines ganzzahligen Atoms ist #dddd, wobei die durch ddddd dargestellten Werte Dezimalstellen sind. Führende Nullen werden ignoriert.
  • Es gibt keine Verweisanzahl oder Speichermehraufwand, die einem ganzzahligen Atom zugeordnet sind.

Atomerstellung und Nutzungsanzahl

Eine Anwendung erstellt ein lokales Atom, indem sie die AddAtom-Funktion aufruft. 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 Zeichenfolgenatoms bereits in der Atomtabelle befindet, erhöht das System während dieses Prozesses die Verweisanzahl für die Zeichenfolge.

Wiederholte Aufrufe zum Hinzufügen desselben Atomnamens geben dasselbe Atom zurück. Wenn der Atomname nicht in der Tabelle 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 Zeichenfolgenatom handelt, wird die Verweisanzahl ebenfalls auf eins 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 Zeichenfolgenatoms reduziert eine dieser Funktionen die Referenzanzahl des entsprechenden Atoms um eins. Wenn die Verweisanzahl 0 erreicht, löscht das System den Atomnamen aus der Tabelle.

Der Atomname eines Zeichenfolgenatoms verbleibt in der globalen Atomtabelle, solange seine Verweisanzahl größer als 0 ist, auch nachdem 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 Referenzanzahl der Atome in der Tabelle.

Atom-Table Abfragen

Eine Anwendung kann mithilfe der Funktion FindAtom oder GlobalFindAtom ermitteln, 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.

Atomzeichenfolgenformate

Die Funktionen AddAtom, GlobalAddAtom, FindAtom und GlobalFindAtom zeigen mit einem Zeiger auf eine Zeichenfolge mit NULL-Beendigung. Eine Anwendung kann diesen Zeiger auf eine der folgenden Arten angeben.

Zeichenfolgenformat Beschreibung
#Dddd Eine ganze Zahl, die als Dezimalzeichenfolge angegeben wird. Wird verwendet, um ein ganzzahliges Atom zu erstellen oder zu finden.
Zeichenfolgenatomname Ein Zeichenfolgenatomname. Wird verwendet, um einer Atomtabelle einen Zeichenfolgenatomnamen hinzuzufügen und im Gegenzug ein Atom zu empfangen.