Tentang Tabel Atom

Tabel atom adalah tabel yang ditentukan sistem yang menyimpan string dan pengidentifikasi terkait. Aplikasi menempatkan string dalam tabel atom dan menerima bilangan bulat 16-bit, yang disebut atom, yang dapat digunakan untuk mengakses string. String yang telah ditempatkan dalam tabel atom disebut nama atom.

Sistem ini menyediakan sejumlah tabel atom. Setiap tabel atom melayani tujuan yang berbeda. Misalnya, aplikasi Dynamic Data Exchange (DDE) menggunakan tabel atom global untuk berbagi string nama item dan nama topik dengan aplikasi lain. Daripada meneruskan string aktual, aplikasi DDE meneruskan atom global ke aplikasi mitranya. Mitra menggunakan atom untuk mendapatkan string dari tabel atom.

Aplikasi dapat menggunakan tabel atom lokal untuk menyimpan asosiasi nama item mereka sendiri.

Sistem ini menggunakan tabel atom yang tidak dapat diakses langsung oleh aplikasi. Namun, aplikasi menggunakan atom ini saat memanggil berbagai fungsi. Misalnya, format clipboard terdaftar disimpan dalam tabel atom internal yang digunakan oleh sistem. Aplikasi menambahkan atom ke tabel atom ini menggunakan fungsi RegisterClipboardFormat. Selain itu, kelas terdaftar disimpan dalam tabel atom internal yang digunakan oleh sistem. Aplikasi menambahkan atom ke tabel atom ini menggunakan fungsi RegisterClass atau RegisterClassEx.

Topik berikut dibahas di bagian ini.

Tabel Atom Global

Tabel atom global tersedia untuk semua aplikasi. Ketika aplikasi menempatkan string dalam tabel atom global, sistem menghasilkan atom yang unik di seluruh sistem. Aplikasi apa pun yang memiliki atom dapat memperoleh string yang diidentifikasinya dengan mengkueri tabel atom global.

Aplikasi yang menentukan format data DDE privat untuk berbagi data dengan aplikasi lain harus menempatkan nama format dalam tabel atom global. Teknik ini mencegah konflik dengan nama format yang ditentukan oleh sistem atau oleh aplikasi lain, dan membuat pengidentifikasi (atom) untuk pesan atau format tersedia untuk aplikasi lain.

Tabel Atom Pengguna

Selain tabel atom global, tabel atom pengguna adalah tabel atom sistem lain yang juga dibagikan di semua proses. Tabel atom pengguna digunakan untuk sejumlah kecil skenario internal untuk win32k; misalnya, nama modul windows, string terkenal dalam format win32k, OLE, dll. Meskipun aplikasi tidak berinteraksi dengan tabel atom pengguna secara langsung, aplikasi memanggil beberapa API—seperti RegisterClass, RegisterWindowMessage, dan RegisterClipboardFormat—yang menambahkan entri ke tabel atom pengguna. Entri yang ditambahkan oleh RegisterClass dapat dihapus oleh UnregisterClass. Namun, entri ditambahkan oleh RegisterWindowMessage dan RegisterClipboardFormat tidak dihapus sampai sesi berakhir. Jika tabel atom pengguna tidak memiliki lebih banyak ruang dan string yang diteruskan belum ada dalam tabel, panggilan akan gagal.

Ukuran Tabel Atom

Banyak API penting, termasuk CreateWindow, mengandalkan atom pengguna. Oleh karena itu, kelelahan ruang dalam tabel atom pengguna akan mengakibatkan masalah serius; misalnya, semua aplikasi mungkin gagal diluncurkan. Berikut adalah beberapa rekomendasi untuk memastikan aplikasi Anda menggunakan tabel atom secara efisien dan mempertahankan keandalan dan performa aplikasi dan sistem:

  1. Anda harus membatasi penggunaan tabel atom pengguna aplikasi Anda. Menyimpan string unik menggunakan API seperti RegisterClass, RegisterWindowMessage, atau RegisterClipboardFormat mengambil ruang dalam tabel atom pengguna, yang digunakan secara global oleh aplikasi lain untuk mendaftarkan kelas jendela menggunakan string. Jika memungkinkan, Anda harus menggunakan AddAtom/DeleteAtom untuk menyimpan string dalam tabel atom lokal, atau GlobalAddAtom/GlobalDeleteAtom jika atom diperlukan lintas proses.

  2. Jika ada kekhawatiran tentang aplikasi yang menyebabkan masalah tabel atom pengguna, Anda dapat menyelidiki akar penyebabnya dengan menghubungkan debugger kernel dan menerobos proses pada panggilan ke UserAddAtomEx (bae1 win32kbase!UserAddAtomEx /p <eprocess> "kc10;g"). Cari user32! di callstack untuk melihat API mana yang sedang dipanggil. Metodologi ini mirip dengan deteksi masalah tabel atom global yang dijelaskan dalam Mengidentifikasi Kebocoran Tabel Atom Global. Cara lain untuk mencadangkan konten tabel atom pengguna adalah dengan memanggil GetClipboardFormatName di atas rentang kemungkinan atom dari 0xC000 ke 0xFFFF. Jika jumlah atom total terus naik saat aplikasi berjalan atau tidak kembali ke garis besar saat aplikasi ditutup, ada masalah.

Tabel Atom Lokal

Aplikasi dapat menggunakan tabel atom lokal untuk mengelola sejumlah besar string yang hanya digunakan dalam aplikasi secara efisien. String ini, dan atom terkait, hanya tersedia untuk aplikasi yang membuat tabel.

Aplikasi yang memerlukan string yang sama dalam sejumlah struktur dapat mengurangi penggunaan memori dengan menggunakan tabel atom lokal. Daripada menyalin string ke dalam setiap struktur, aplikasi dapat menempatkan string dalam tabel atom dan menyertakan atom yang dihasilkan dalam struktur. Dengan cara ini, string hanya muncul sekali dalam memori tetapi dapat digunakan berkali-kali dalam aplikasi.

Aplikasi juga dapat menggunakan tabel atom lokal untuk menghemat waktu saat mencari string tertentu. Untuk melakukan pencarian, aplikasi hanya perlu menempatkan string pencarian dalam tabel atom dan membandingkan atom yang dihasilkan dengan atom dalam struktur yang relevan. Membandingkan atom biasanya lebih cepat daripada membandingkan string.

Tabel atom diimplementasikan sebagai tabel hash. Secara default, tabel atom lokal menggunakan 37 wadah untuk tabel hash-nya. Namun, Anda dapat mengubah jumlah wadah yang digunakan dengan memanggil fungsi InitAtomTable. Namun, jika aplikasi memanggil InitAtomTable, aplikasi harus melakukannya sebelum memanggil fungsi manajemen atom lainnya.

Jenis Atom

Aplikasi dapat membuat dua jenis atom: atom string dan atom bilangan bulat. Nilai atom bilangan bulat dan atom string tidak tumpang tindih, sehingga kedua jenis atom dapat digunakan dalam blok kode yang sama.

Beberapa fungsi menerima string atau atom sebagai parameter. Saat meneruskan atom ke fungsi-fungsi ini, aplikasi dapat menggunakan makro MAKEINTATOM untuk mengonversi atom menjadi bentuk yang dapat digunakan oleh fungsi.

Bagian berikut menjelaskan jenis atom.

Atom String

Ketika aplikasi meneruskan string yang dihentikan null ke fungsi GlobalAddAtom, AddAtom, GlobalFindAtom, dan FindAtom, aplikasi menerima atom string (bilangan bulat 16-bit) sebagai gantinya. Atom string memiliki properti berikut:

  • Nilai atom string berada dalam rentang 0xC000 (MAXINTATOM) melalui 0xFFFF.
  • Kasus tidak signifikan dalam pencarian nama atom dalam tabel atom. Selain itu, seluruh string harus cocok dalam operasi pencarian; tidak ada pencocokan substring yang dilakukan.
  • String yang terkait dengan atom string tidak boleh berukuran tidak lebih dari 255 byte. Batasan ini berlaku untuk semua fungsi atom.
  • Jumlah referensi dikaitkan dengan setiap nama atom. Jumlah bertambah setiap kali nama atom ditambahkan ke tabel dan diderementasikan setiap kali nama atom dihapus darinya. Ini mencegah pengguna yang berbeda dari atom string yang sama menghancurkan nama atom satu sama lain. Ketika jumlah referensi untuk nama atom sama dengan nol, sistem menghapus atom dan nama atom dari tabel.

Atom Bilangan Bulat

Atom bilangan bulat berbeda dari atom string dengan cara berikut:

  • Nilai atom bilangan bulat berada dalam rentang 0x0001 hingga 0xBFFF (MAXINTATOM– 1).
  • Representasi string dari atom bilangan bulat adalah #dddd, di mana nilai yang diwakili oleh dddd adalah digit desimal. Nol di depan diabaikan.
  • Tidak ada jumlah referensi atau overhead penyimpanan yang terkait dengan atom bilangan bulat.

Pembuatan dan Jumlah Penggunaan Atom

Aplikasi membuat atom lokal dengan memanggil fungsi AddAtom; ini menciptakan atom global dengan memanggil fungsi GlobalAddAtom. Kedua fungsi memerlukan penunjuk ke string. Sistem mencari tabel atom yang sesuai untuk string dan mengembalikan atom yang sesuai dengan aplikasi. Dalam kasus atom string, jika string sudah berada di tabel atom, sistem akan menaikkan jumlah referensi untuk string selama proses ini.

Panggilan berulang untuk menambahkan nama atom yang sama mengembalikan atom yang sama. Jika nama atom tidak ada dalam tabel saat AddAtom dipanggil, nama atom ditambahkan ke tabel dan atom baru dikembalikan. Jika itu adalah atom string, jumlah referensinya juga diatur ke satu.

Aplikasi harus memanggil fungsi DeleteAtom ketika tidak lagi perlu menggunakan atom lokal; aplikasi harus memanggil fungsi GlobalDeleteAtom ketika tidak lagi membutuhkan atom global. Dalam kasus atom string, salah satu fungsi ini mengurangi jumlah referensi atom yang sesuai satu per satu. Ketika jumlah referensi mencapai nol, sistem menghapus nama atom dari tabel.

Nama atom atom string tetap berada dalam tabel atom global selama jumlah referensinya lebih besar dari nol, bahkan setelah aplikasi yang menempatkannya dalam tabel berakhir. Tabel atom lokal dihancurkan ketika aplikasi terkait berakhir, terlepas dari jumlah referensi atom dalam tabel.

Kueri Tabel Atom

Aplikasi dapat menentukan apakah string tertentu sudah ada dalam tabel atom dengan menggunakan fungsi FindAtom atau GlobalFindAtom. Fungsi-fungsi ini mencari tabel atom untuk string yang ditentukan dan, jika string ada, kembalikan atom yang sesuai.

Aplikasi dapat menggunakan fungsi GetAtomName atau GlobalGetAtomName untuk mengambil string nama atom dari tabel atom, asalkan aplikasi memiliki atom yang sesuai dengan string yang sedang dicari. Kedua fungsi menyalin string nama atom dari atom yang ditentukan ke buffer dan mengembalikan panjang string yang disalin. GetAtomName mengambil string nama atom dari tabel atom lokal, dan GlobalGetAtomName mengambil string nama atom dari tabel atom global.

Format String Atom

Fungsi AddAtom, GlobalAddAtom, FindAtom, dan GlobalFindAtom mengambil penunjuk ke string null-terminated. Aplikasi dapat menentukan penunjuk ini dengan salah satu cara berikut.

Format string Deskripsi
#dddd Bilangan bulat yang ditentukan sebagai string desimal. Digunakan untuk membuat atau menemukan atom bilangan bulat.
nama atom string Nama atom string. Digunakan untuk menambahkan nama atom string ke tabel atom dan menerima atom sebagai gantinya.