Pada artikel ini, kami menyajikan
halaman , skema manajemen memori yang sangat umum yang juga kami terapkan di OS kami. Artikel ini menjelaskan mengapa isolasi memori diperlukan, bagaimana
segmentasi bekerja, apa
memori virtual itu, dan bagaimana halaman memecahkan masalah fragmentasi. Kami juga menjelajahi skema tabel halaman bertingkat dalam arsitektur x86_64.
Blog ini diposting di
GitHub . Jika Anda memiliki pertanyaan atau masalah, buka permintaan terkait di sana.
Perlindungan memori
Salah satu tugas utama sistem operasi adalah mengisolasi program dari satu sama lain. Misalnya, browser tidak boleh mengganggu editor teks. Ada berbagai pendekatan tergantung pada implementasi perangkat keras dan OS.
Sebagai contoh, beberapa prosesor ARM Cortex-M (dalam embedded system) memiliki
unit proteksi memori (MPU) yang mendefinisikan sejumlah kecil (misalnya, 8) area memori dengan izin akses yang berbeda (misalnya, tidak ada akses, hanya baca, baca dan catatan). Setiap kali memori diakses, MPU memastikan bahwa alamatnya berada di area dengan izin yang benar, jika tidak maka akan melempar pengecualian. Dengan mengubah ruang lingkup dan izin akses, OS memastikan bahwa setiap proses hanya memiliki akses ke memorinya untuk mengisolasi proses dari satu sama lain.
Pada x86, dua pendekatan berbeda untuk melindungi memori didukung:
segmentasi dan
paging .
Segmentasi
Segmentasi diterapkan kembali pada tahun 1978, awalnya untuk meningkatkan jumlah memori addressable. Pada saat itu, CPU hanya mendukung alamat 16-bit, yang membatasi jumlah memori yang dapat dialamatkan hingga 64 KB. Untuk meningkatkan volume ini, register segmen tambahan diperkenalkan, yang masing-masing berisi alamat offset. CPU secara otomatis menambahkan offset ini pada setiap akses memori, sehingga menangani memori hingga 1 MB.
CPU secara otomatis memilih register segmen tergantung pada jenis akses memori: register segmen kode
CS
digunakan untuk menerima instruksi, dan register segmen stack
SS
digunakan untuk operasi stack (push / pop). Instruksi lain menggunakan register segmen data
DS
atau register segmen
ES
opsional. Kemudian, dua register segmen tambahan
FS
dan
GS
ditambahkan secara gratis.
Dalam versi pertama segmentasi, register secara langsung berisi offset dan kontrol akses tidak dilakukan. Dengan munculnya
mode terlindungi, mekanismenya telah berubah. Saat CPU beroperasi dalam mode ini, deskriptor segmen menyimpan indeks dalam tabel deskriptor lokal atau global, yang selain alamat offset berisi ukuran segmen dan izin akses. Dengan memuat tabel deskriptor global / lokal yang terpisah untuk setiap proses, OS dapat mengisolasi proses satu sama lain.
Dengan mengubah alamat memori sebelum akses aktual, segmentasi menerapkan metode yang sekarang digunakan hampir di mana-mana: itu adalah
memori virtual .
Memori virtual
Ide memori virtual adalah untuk mengabstraksi alamat memori dari perangkat fisik. Alih-alih langsung mengakses perangkat penyimpanan, langkah konversi terlebih dahulu dilakukan. Dalam hal segmentasi, alamat offset segmen aktif ditambahkan pada tahap terjemahan. Bayangkan sebuah program yang mengakses alamat memori
0x1234000
dalam sebuah segmen dengan offset
0x1111000
: pada kenyataannya, alamatnya menjadi
0x2345000
.
Untuk membedakan antara dua jenis alamat, alamat sebelum konversi disebut
virtual , dan alamat setelah konversi disebut
fisik . Ada satu perbedaan penting di antara mereka: alamat fisik adalah unik dan selalu merujuk ke lokasi unik yang sama dalam memori. Alamat virtual, di sisi lain, bergantung pada fungsi terjemahan. Dua alamat virtual yang berbeda mungkin merujuk ke alamat fisik yang sama. Selain itu, alamat virtual yang identik dapat merujuk ke berbagai alamat fisik setelah konversi.
Contoh penggunaan yang berguna dari properti ini adalah peluncuran paralel dari program yang sama dua kali:

Di sini, program yang sama berjalan dua kali, tetapi dengan fungsi konversi yang berbeda. Contoh pertama memiliki offset segmen 100, sehingga alamat virtualnya 0-150 dikonversi ke alamat fisik 100-250. Contoh kedua memiliki offset 300, yang menerjemahkan alamat virtual 0-150 menjadi alamat fisik 300-450. Ini memungkinkan kedua program untuk mengeksekusi kode yang sama dan menggunakan alamat virtual yang sama tanpa mengganggu satu sama lain.
Keuntungan lain adalah bahwa sekarang program dapat ditempatkan di tempat sewenang-wenang di memori fisik. Dengan demikian, OS menggunakan seluruh jumlah memori yang tersedia tanpa perlu mengkompilasi ulang program.
Fragmentasi
Perbedaan antara alamat virtual dan fisik adalah pencapaian segmentasi yang nyata. Tapi ada masalah. Bayangkan kita ingin menjalankan salinan ketiga dari program yang kita lihat di atas:

Meskipun ada lebih dari cukup ruang dalam memori fisik, salinan ketiga tidak cocok di mana pun. Masalahnya adalah ia membutuhkan fragmen memori yang
berkelanjutan dan kami tidak dapat menggunakan bagian bebas yang terpisah.
Salah satu cara untuk memerangi fragmentasi adalah menghentikan sementara eksekusi program, memindahkan bagian memori yang digunakan lebih dekat satu sama lain, memperbarui konversi, dan kemudian melanjutkan eksekusi:

Sekarang ada cukup ruang untuk meluncurkan instance ketiga.
Kerugian dari defragmentasi ini adalah kebutuhan untuk menyalin sejumlah besar memori, yang mengurangi kinerja. Prosedur ini harus dilakukan secara teratur sampai memori menjadi terlalu terfragmentasi. Kinerja menjadi tidak dapat diprediksi, program berhenti kapan saja dan dapat berhenti merespons.
Fragmentasi adalah salah satu alasan mengapa segmentasi tidak digunakan di sebagian besar sistem. Bahkan, itu tidak lagi didukung bahkan dalam mode 64-bit pada x86. Alih-alih segmentasi, halaman digunakan yang sepenuhnya menghilangkan masalah fragmentasi.
Halaman organisasi memori
Idenya adalah untuk membagi ruang memori virtual dan fisik menjadi blok kecil dengan ukuran tetap. Blok memori virtual disebut halaman, dan blok ruang alamat fisik disebut frame. Setiap halaman secara individual dipetakan ke sebuah frame, yang memungkinkan Anda untuk membagi area memori yang besar antara frame fisik yang tidak berdekatan.
Keuntungannya menjadi jelas jika Anda mengulangi contoh dengan ruang memori yang terfragmentasi, tetapi kali ini menggunakan halaman alih-alih segmentasi:

Dalam contoh ini, ukuran halaman adalah 50 byte, yaitu, masing-masing area memori dibagi menjadi tiga halaman. Setiap halaman dipetakan ke frame yang terpisah, sehingga wilayah memori virtual yang berdekatan dapat dipetakan ke frame fisik yang terisolasi. Ini memungkinkan Anda untuk menjalankan instance ketiga program tanpa defragmentasi.
Fragmentasi tersembunyi
Dibandingkan dengan segmentasi, organisasi paging menggunakan banyak area memori berukuran kecil dan bukannya beberapa area berukuran variabel. Setiap frame memiliki ukuran yang sama, jadi fragmentasi karena frame terlalu kecil tidak dimungkinkan.
Tapi ini hanya
penampilan . Bahkan, ada bentuk fragmentasi tersembunyi, yang disebut
fragmentasi internal karena fakta bahwa tidak setiap area memori persis kelipatan dari ukuran halaman. Bayangkan dalam contoh di atas, program ukuran 101: masih akan membutuhkan tiga halaman ukuran 50, sehingga akan membutuhkan 49 byte lebih dari yang Anda butuhkan. Untuk kejelasan, fragmentasi karena segmentasi disebut
fragmentasi eksternal .
Tidak ada yang baik dalam fragmentasi internal, tetapi seringkali itu adalah kejahatan yang lebih rendah daripada fragmentasi eksternal. Memori tambahan masih dikonsumsi, tetapi sekarang Anda tidak perlu men-defragnya, dan volume fragmentasi dapat diprediksi (rata-rata, setengah halaman per area memori).
Tabel Halaman
Kami melihat bahwa masing-masing dari jutaan halaman yang mungkin dipetakan secara individual ke sebuah bingkai. Informasi terjemahan alamat ini perlu disimpan di suatu tempat. Saat melakukan segmentasi, register segmen yang terpisah digunakan untuk setiap area memori aktif, yang tidak mungkin dalam hal halaman, karena ada lebih banyak dari mereka daripada register. Sebagai gantinya, ia menggunakan struktur yang disebut
tabel halaman .
Untuk contoh di atas, tabel akan terlihat seperti ini:

Seperti yang Anda lihat, setiap instance dari program memiliki tabel halaman sendiri. Sebuah penunjuk ke tabel aktif saat ini disimpan dalam register khusus CPU. Pada
x86
itu disebut
CR3
. Sebelum memulai setiap instance program, sistem operasi harus memuat pointer ke tabel halaman yang benar di sana.
Setiap kali memori diakses, CPU membaca pointer tabel dari register dan mencari frame yang sesuai dalam tabel. Ini adalah fungsi perangkat keras sepenuhnya yang berjalan sepenuhnya transparan untuk program yang sedang berjalan. Untuk mempercepat proses, banyak arsitektur prosesor memiliki cache khusus yang mengingat hasil konversi terbaru.
Bergantung pada arsitektur, atribut seperti izin juga dapat disimpan di bidang bendera pada tabel halaman. Pada contoh di atas, bendera
r/w
membuat halaman dapat dibaca dan ditulis.
Tabel Halaman Layered
Tabel halaman sederhana memiliki masalah dengan ruang alamat yang besar: memori terbuang sia-sia. Misalnya, program ini menggunakan empat halaman virtual
0
,
1_000_000
,
1_000_050
dan
1_000_100
(kami menggunakan
_
sebagai pemisah angka):

Hanya empat bingkai fisik yang diperlukan, tetapi ada lebih dari satu juta catatan dalam tabel halaman. Kami tidak dapat melewati entri kosong, karena dengan demikian CPU selama proses konversi tidak akan dapat langsung masuk ke entri yang benar (misalnya, tidak lagi dijamin bahwa halaman keempat menggunakan entri keempat).
Untuk mengurangi kehilangan memori, Anda dapat menggunakan organisasi
dua tingkat . Idenya adalah kita menggunakan tabel yang berbeda untuk area yang berbeda. Tabel tambahan, disebut tabel halaman
level kedua , mengkonversi antara area alamat dan tabel halaman level pertama.
Ini paling baik dijelaskan dengan contoh. Kami menetapkan bahwa setiap tabel halaman level 1 bertanggung jawab untuk area dengan ukuran
10_000
. Maka dalam contoh di atas tabel berikut akan ada:

Halaman 0 jatuh ke area pertama
10_000
byte, sehingga menggunakan catatan pertama di tabel halaman tingkat kedua. Entri ini menunjuk ke tabel halaman T1 tingkat pertama, yang menentukan bahwa halaman 0 mengacu pada frame 0.
Halaman
1_000_000
,
1_000_050
dan
1_000_100
termasuk dalam wilayah byte ke-
10_000
dari
10_000
, sehingga mereka menggunakan catatan ke-100 tabel tabel level 2. Catatan ini menunjuk ke tabel level pertama lain T2, yang menerjemahkan tiga halaman menjadi frame 100, 150 dan 200. Catatan bahwa alamat halaman dalam tabel di tingkat pertama tidak mengandung offset wilayah, oleh karena itu, misalnya, catatan untuk halaman
1_000_050
hanya
50
.
Kami masih memiliki 100 entri kosong di tabel tingkat kedua, tetapi ini jauh lebih sedikit daripada juta sebelumnya. Alasan penghematan adalah bahwa Anda tidak perlu membuat tabel halaman tingkat pertama untuk area memori yang
10_000
antara
10_000
dan
1_000_000
.
Prinsip tabel dua tingkat dapat diperpanjang hingga tiga, empat tingkat atau lebih. Secara umum, sistem seperti itu disebut tabel halaman
bertingkat atau
hierarkis .
Mengetahui organisasi halaman dan tabel multi-level, Anda dapat melihat bagaimana organisasi halaman diimplementasikan dalam arsitektur x86_64 (kami mengasumsikan bahwa prosesor berjalan dalam mode 64-bit).
Organisasi Halaman di x86_64
Arsitektur x86_64 menggunakan tabel empat tingkat dengan ukuran halaman 4 KB. Terlepas dari level, setiap tabel halaman memiliki 512 elemen. Setiap record memiliki ukuran 8 byte, sehingga ukuran tabel adalah 512 Γ 8 byte = 4 KB.

Seperti yang Anda lihat, setiap indeks tabel berisi 9 bit, yang masuk akal, karena tabel memiliki 2 ^ 9 = 512 entri. 12 bit terbawah adalah offset halaman 4-kilobyte (2 ^ 12 byte = 4 KB). Bit 48 hingga 64 dibuang, jadi x86_64 sebenarnya bukan sistem 64-bit, tetapi hanya mendukung alamat 48-bit. Ada rencana untuk memperluas ukuran alamat menjadi 57 bit melalui
tabel halaman 5 tingkat , tetapi prosesor seperti itu belum dibuat.
Meskipun bit 48 hingga 64 dibuang, mereka tidak dapat diatur ke nilai arbitrer. Semua bit dalam kisaran ini harus merupakan salinan bit 47 untuk mempertahankan alamat unik dan memungkinkan ekspansi di masa mendatang, misalnya, ke tabel halaman 5-tingkat. Ini disebut ekstensi tanda, karena sangat mirip dengan
ekstensi tanda pada kode tambahan . Jika alamat tidak diperluas dengan benar, CPU melempar pengecualian.
Contoh konversi
Mari kita lihat contoh cara kerja terjemahan alamat:

Alamat fisik dari tabel halaman aktif saat ini dari level 4 halaman, yang merupakan tabel root dari halaman halaman level ini, disimpan dalam
CR3
. Setiap entri tabel halaman kemudian menunjuk ke bingkai fisik dari tabel level berikutnya. Entri tabel level 1 menunjukkan bingkai yang ditampilkan. Harap perhatikan bahwa semua alamat dalam tabel halaman bersifat fisik dan bukan virtual, karena jika tidak, CPU harus mengubah alamat ini (yang dapat menyebabkan rekursi tak terbatas).
Hirarki di atas mengonversi dua halaman (berwarna biru). Dari indeks, kita dapat menyimpulkan bahwa alamat virtual dari halaman ini adalah
0x803fe7f000
dan
0x803FE00000
. Mari kita lihat apa yang terjadi ketika sebuah program mencoba membaca memori di alamat
0x803FE7F5CE
. Pertama, ubah alamat menjadi biner dan tentukan indeks tabel halaman dan offset untuk alamat:

Dengan menggunakan indeks ini, kita sekarang bisa melalui hierarki tabel halaman dan menemukan bingkai yang sesuai:
- Baca alamat tabel level keempat dari
CR3
. - Indeks level keempat adalah 1, jadi kami melihat catatan dengan indeks 1 dalam tabel ini. Dia mengatakan tabel level 3 disimpan pada 16 KB.
- Kami memuat tabel tingkat ketiga dari alamat ini dan melihat catatan dengan indeks 0, yang menunjuk ke tabel tingkat kedua pada 24 KB.
- Indeks level kedua adalah 511, jadi kami mencari catatan terakhir pada halaman ini untuk mengetahui alamat tabel level pertama.
- Dari entri dengan indeks 127 pada tabel tingkat pertama, kami akhirnya menemukan bahwa halaman tersebut sesuai dengan bingkai 12 KB atau 0xc000 dalam format heksadesimal.
- Langkah terakhir adalah menambahkan offset ke alamat bingkai untuk mendapatkan alamat fisik: 0xc000 + 0x5ce = 0xc5ce.

Untuk halaman di tabel level pertama,
r
bendera ditentukan, yaitu, hanya bacaan yang diizinkan. Pengecualian akan dilemparkan ke tingkat perangkat keras jika kami mencoba merekam di sana. Izin tabel level yang lebih tinggi meluas ke level yang lebih rendah, jadi jika kita mengatur flag read-only pada level ketiga, tidak ada satu halaman berikutnya dari level yang lebih rendah yang dapat ditulisi, bahkan jika ada flag yang memungkinkan penulisan.
Meskipun contoh ini hanya menggunakan satu instance dari setiap tabel, biasanya di setiap ruang alamat ada beberapa contoh dari setiap level. Maksimal:
- satu meja dari tingkat keempat,
- 512 tabel dari level ketiga (karena ada 512 catatan di tabel level keempat),
- 512 * 512 tabel tingkat kedua (karena masing-masing tabel tingkat ketiga memiliki 512 entri), dan
- 512 * 512 * 512 tabel di tingkat pertama (512 catatan untuk setiap tabel di tingkat kedua).
Format Tabel Halaman
Dalam arsitektur x86_64, tabel halaman pada dasarnya adalah array dari 512 entri. Dalam sintaksis Rust:
#[repr(align(4096))] pub struct PageTable { entries: [PageTableEntry; 512], }
Seperti yang ditunjukkan pada atribut
repr
, tabel harus disejajarkan pada halaman, mis., Pada batas 4 KB. Persyaratan ini memastikan bahwa tabel selalu secara optimal mengisi seluruh halaman, membuat entri menjadi sangat ringkas.
Ukuran setiap catatan adalah 8 byte (64 bit) dan format berikut:
Bit | Judul | Nilai |
---|
0 | hadir | halaman dalam memori |
1 | dapat ditulis | catatan diizinkan |
2 | pengguna dapat diakses | jika bit tidak diset, maka hanya kernel yang memiliki akses ke halaman |
3 | tuliskan melalui caching | menulis langsung ke memori |
4 | nonaktifkan cache | nonaktifkan cache untuk halaman ini |
5 | diakses | CPU menyetel bit ini saat halaman sedang digunakan. |
6 | kotor | CPU menetapkan bit ini saat menulis ke halaman |
7 | halaman besar / nol | bit nol di P1 dan P4 menciptakan 1 halaman KB di P3, halaman 2 MB di P2 |
8 | global | halaman tidak diisi dari cache ketika berpindah ruang alamat (bit PGE dari register CR4 harus disetel) |
9-11 | tersedia | OS dapat menggunakannya secara bebas |
12-51 | alamat fisik | alamat fisik frame-aligned 52-bit dari frame atau tabel halaman berikut |
52-62 | tersedia | OS dapat menggunakannya secara bebas |
63 | tidak ada eksekusi | melarang eksekusi kode pada halaman ini (bit NXE harus diatur dalam register EFER) |
Kita melihat bahwa hanya bit 12-51 yang digunakan untuk menyimpan alamat fisik frame, dan sisanya berfungsi sebagai flag atau dapat digunakan secara bebas oleh sistem operasi. Ini dimungkinkan karena kami selalu menunjuk ke alamat rata-rata 4096-byte, atau ke halaman tabel yang selaras, atau ke awal frame yang sesuai. Ini berarti bahwa bit 0-11 selalu nol, sehingga tidak dapat disimpan, mereka cukup direset ke tingkat perangkat keras sebelum menggunakan alamat. Hal yang sama berlaku untuk bit 52-63, karena arsitektur x86_64 hanya mendukung alamat fisik 52-bit (dan hanya alamat virtual 48-bit).
Mari kita lihat lebih dekat bendera yang tersedia:
- Bendera ini membedakan halaman yang ditampilkan dari yang tidak ditampilkan. Ini dapat digunakan untuk menyimpan sementara halaman ke disk ketika memori utama penuh. Saat berikutnya halaman diakses, pengecualian PageFault khusus terjadi, di mana OS merespons dengan menukar halaman dari disk - program terus bekerja.
- Flag yang
writable
dan no execute
menentukan apakah konten halaman dapat ditulisi atau masing-masing berisi instruksi yang dapat dieksekusi. - Bendera yang
accessed
dan dirty
secara otomatis diatur oleh prosesor saat membaca atau menulis ke halaman. OS dapat menggunakan informasi ini, misalnya, jika bertukar halaman atau ketika memeriksa untuk melihat apakah isi halaman telah berubah sejak pemompaan terakhir ke disk. - Tulisan
write through caching
dan disable cache
flag disable cache
memungkinkan Anda mengelola cache untuk setiap halaman secara individual. - Bendera yang
user accessible
membuat halaman dapat diakses untuk kode dari ruang pengguna, jika tidak, hanya tersedia untuk kernel. Fungsi ini dapat digunakan untuk mempercepat panggilan sistem sambil mempertahankan pemetaan alamat untuk kernel saat program pengguna sedang berjalan. Namun, kerentanan Spectre memungkinkan halaman ini dibaca oleh program dari ruang pengguna. global
, (. TLB ) (address space switch). user accessible
.huge page
, 2 3 . 512 : 2 = 512 Γ 4 , 1 = 512 Γ 2 . .
Arsitektur x86_64 mendefinisikan format tabel halaman dan rekamannya , jadi kami tidak harus membuat struktur ini sendiri.Buffer Terjemahan Asosiatif (TLB)
- . x86_64 (TLB). , .
, TLB , . , TLB , . CPU
invlpg
(invalidate page), TLB, . TLB
CR3
yang meniru saklar ruang alamat. Kedua opsi tersedia melalui modul tlb di Rust.Penting untuk diingat untuk membersihkan TLB setelah setiap perubahan tabel halaman, jika tidak CPU akan terus menggunakan terjemahan yang lama, yang akan menyebabkan kesalahan tak terduga yang sangat sulit untuk di-debug.Implementasi
:
.
Β« RustΒ» , , 64- x86_64.
, . VGA
0xb8000
,
,
0xb8000
0xb8000
.
: , . : ,
(PageFault)
PageFault, . -, IDT,
:
CPU
CR2
. , .
Cr2::read
.
PageFaultErrorCode
, -
LLVM , . , ,
hlt_loop
.
:
Setelah memulai, kita melihat bahwa penangan kesalahan halaman disebut:
Register CR2
benar-benar berisi alamat yang 0xdeadbeaf
ingin kita akses.Pointer instruksi saat ini adalah 0x20430a
, jadi kami tahu bahwa alamat ini menunjuk ke halaman kode. Halaman kode ditampilkan oleh loader read-only, jadi membaca dari alamat ini berfungsi, dan penulisan akan menyebabkan kesalahan. Coba ubah pointer 0xdeadbeaf
ke 0x20430a
:
Jika kami mengomentari baris terakhir, kami dapat memastikan bahwa bacaan berfungsi, dan penulisan menyebabkan kesalahan PageFault.Akses ke tabel halaman
Sekarang lihat tabel halaman untuk kernel:
Cr3::read
x86_64
CR3
.
PhysFrame
Cr3Flags
. .
:
Level 4 page table at: PhysAddr(0x1000)
,
0x1000
,
PhysAddr
. : ?
, . , β ,
0x1000
. Ini adalah masalah umum karena kernel harus secara teratur mengakses tabel halaman, misalnya, ketika mengalokasikan tumpukan untuk utas baru.Solusi untuk masalah ini akan dijelaskan secara rinci di artikel selanjutnya. Untuk saat ini, katakan saja bahwa loader menggunakan metode yang disebut tabel halaman rekursif . Halaman terakhir dari ruang alamat virtual adalah 0xffff_ffff_ffff_f000
, kami menggunakannya untuk membaca beberapa entri dalam tabel ini:
u64
. , 8 (64 ),
u64
.
for
10 .
offset
.
:

,
0x2023
0
present
,
writable
,
accessed
0x2000
. 1
0x6e2000
,
dirty
. Entri 2β9 tidak ada, jadi rentang alamat virtual ini tidak dipetakan ke alamat fisik apa pun.Alih-alih bekerja dengan pointer yang tidak aman secara langsung, Anda dapat menggunakan tipe PageTable
dari x86_64
:
0xffff_ffff_ffff_f000
, Rust. - , , .
&PageTable
, ,
.
x86_64
, :

β 0 1 3. ,
0x2000
0x6e5000
, . .
Ringkasan
Artikel ini menyajikan dua metode melindungi memori: segmentasi dan pengorganisasian halaman. Metode pertama menggunakan area memori berukuran variabel dan menderita fragmentasi eksternal, yang kedua menggunakan halaman berukuran tetap dan memungkinkan kontrol granular lebih besar atas hak akses.Organisasi halaman menyimpan informasi terjemahan halaman dalam tabel-tabel dari satu level atau lebih. Arsitektur x86_64 menggunakan tabel empat tingkat dengan ukuran halaman 4 KB. Peralatan secara otomatis mem-bypass tabel halaman dan menyimpan hasil konversi dalam buffer terjemahan asosiatif (TLB). Saat mengganti tabel halaman, harus dipaksa untuk membersihkan., , PageFault. , , , .
Apa selanjutnya
, .
, . , .