Kedalaman memori Windows (bagian 1) — Saat alamat virtual menjadi RAM fisik: page fault dari awal sampai akhir

· Diperbarui pada: · · Windows, Manajemen memori, VirtualAlloc, Page fault, VAD, Pemantauan kinerja

Riwayat revisi (1 pembaruan, terakhir pada 31 Aug 2026)

Catatan perubahan yang dilakukan pada artikel ini. Jika versi sebelumnya telah diarsipkan, versi itu tetap dapat dibaca melalui tautan permanen dengan DOI.

Diterjemahkan ulang sebagai terjemahan lengkap dari naskah Jepang. Versi bahasa Indonesia sebelumnya adalah ringkasan yang hanya memindahkan sebagian naskah, sehingga bagian, tabel, gambar Mermaid, keterangan gambar, dan FAQ tidak ada. Semuanya dipulihkan sesuai naskah Jepang, dan klaim teknisnya sama dengan versi Jepang.
Publikasi pertama
Mengutip artikel ini(DOI (arsip terdaftar): 10.5281/zenodo.22176080)

DOI di bawah mengarah ke versi yang telah diarsipkan sebelumnya dan mungkin berbeda dari teks saat ini. Gunakan URL halaman ini untuk merujuk teks saat ini.

Go Komura (2026). Kedalaman memori Windows (bagian 1) — Saat alamat virtual menjadi RAM fisik: page fault dari awal sampai akhir. KomuraSoft LLC. https://comcomponent.com/id/blog/windows-memory-internals-page-fault/

DOI (arsip terdaftar)
10.5281/zenodo.22176080
DOI (versi terakhir yang didaftarkan)
10.5281/zenodo.22176081

Saat MEM_COMMIT diserahkan ke VirtualAlloc, Commit naik pada saat itu juga. Working Set, sebaliknya, tidak selalu naik sebesar itu. Lalu di mana memori yang seolah sudah dialokasikan itu?

Jawabannya: pada sebagian besar halaman, RAM fisik yang sesuai belum ada. Windows menunda alokasi halaman fisik sampai aplikasi benar-benar menyentuh halaman itu. Ketika akses pertama membuat CPU menaikkan page fault, manajer memori memeriksa VAD, PTE, atribut proteksi, dan backing store, lalu mengikat RAM satu halaman pada satu waktu jika perlu.1

Artikel ini menelusuri jalan dari «satu byte yang pertama kali disentuh» sampai RAM fisik. Jika makna angka seperti Working Set dan Commit ingin dirapikan lebih dulu, lihat artikel pengantar «Apa arti “pemakaian memori” Windows sebenarnya? — Membaca Working Set, Private Bytes, Commit, dan page file dengan benar». Serial ini tidak mendefinisikan ulang istilah di artikel itu; ia menelusuri dari sisi mekanisme mengapa angka itu terbentuk.

«Kedalaman memori Windows» — tiga bagian

  1. Bagian 1 (artikel ini): alamat virtual dan page fault
    Kapan wilayah hasil VirtualAlloc memperoleh RAM fisik.
  2. Bagian 2: hidup sebuah halaman fisik
    Bagaimana halaman yang keluar dari Working Set berpindah melalui Modified, Standby, Free, dan Zeroed.
  3. Bagian 3: objek section dan copy-on-write
    Mengapa DLL, pemetaan berkas, dan memori bersama dapat berbagi halaman fisik.

Pertanyaan yang dijawab bagian 1 hanya satu.

Pada saat mana alamat virtual yang sudah di-Commit menjadi RAM fisik?

Pembaca yang dituju adalah pengembang dan operator yang ingin memahami, dari mekanismenya, pemakaian memori aplikasi Windows, page fault tepat setelah startup, 0xC0000005, serta angka di VMMap dan PerfMon. Prasyarat lingkungan adalah Windows 10/11 atau Windows Server terkini. Latar yang dibutuhkan adalah pointer dan dasar VirtualAlloc; pengalaman tata letak bit tabel halaman atau debugger kernel tidak diperlukan. Tingkat kesulitannya menengah. Nama struktur internal dipakai, tetapi tata letak tidak terdokumentasi yang bergantung pada build Windows tertentu tidak dijadikan prasyarat.

Pada diagram, garis utuh menunjukkan relasi yang selalu berlaku dan garis putus-putus menunjukkan relasi bersyarat (syaratnya ada pada penjelasan masing-masing relasi di halaman rincian). Daftar lengkap relasi (total 14, beserta bukti dan tingkat kepastian) serta definisi konsep utama dikumpulkan di halaman rincian peta pengetahuan (dalam bahasa Jepang). Data: JSON-LD / Turtle

1. Kesimpulan dulu

Alur memori privat biasa, dalam satu baris, adalah sebagai berikut.

Reserve menyisihkan rentang alamat virtual, Commit membebankan commit charge untuk menjamin tempat penyimpanan di kemudian hari, dan page fault pada akses pertama mengalokasikan halaman fisik.

Dengan kata lain, MEM_COMMIT bukan perintah «alokasikan RAM sekarang». Dokumentasi Microsoft untuk VirtualAlloc juga menjamin isi awal halaman yang sudah di-Commit bernilai nol, sambil menjelaskan bahwa halaman fisik sebenarnya belum dialokasikan sampai alamat virtual diakses.1

Mengatakan «Reserve/Commit hanya menulis ke VAD» juga tidak akurat. Pada praktiknya, Reserve terutama membuat VAD yang merepresentasikan rentang alamat virtual dan atributnya, sedangkan Commit menaikkan Commit Total sistem dan mencatat keadaan commit rentang itu. Tingkat perantara tabel halaman dan PTE individual dibangun secara tertunda saat dibutuhkan, dan pengikatan akhir ke RAM fisik biasanya terjadi pada akses pertama.

Commit bukan janji kosong; itu janji se-sistem bahwa isinya dapat disimpan di kemudian hari di RAM atau backing store yang sesuai. Titik masuk yang mewujudkan janji itu, satu halaman pada satu waktu, adalah page fault.

Apa yang terjadi pada Reserve, Commit, dan akses pertamaMEM_RESERVE mencatat rentang dan atribut di VAD, MEM_COMMIT mengonsumsi Commit Total untuk menjanjikan penyimpanan, dan page fault pada akses pertama mengalokasikan halaman fisik lalu menambahkannya ke Working Set1. MEM_RESERVE2. MEM_COMMIT3. Akses pertama (Touch)Catat rentang dan atribut di VADKonsumsi Commit Total (halaman fisik belum ada)page faultIkat halaman fisik yang sudah nol ke PTETambahkan ke Working Set dan jalankan ulang instruksi

Gambar 1: Reserve, Commit, dan Touch adalah peristiwa terpisah. RAM fisik terikat hanya pada langkah terakhir, yaitu akses pertama.

2. Tiga buku besar yang menelusuri halaman virtual

Untuk memahami jalan dari alamat virtual ke RAM fisik, tiga jenis buku besar yang dipegang Windows perlu dibedakan.

Buku besar Satuan Peran
VAD Rentang alamat virtual Mengelola jenis wilayah, Reserve/Commit, proteksi, dan korespondensi section
Tabel halaman / PTE Halaman virtual Mewakili terjemahan saat ini ke halaman fisik, atau keadaan yang belum diwujudkan
Basis data PFN Halaman fisik Melacak kepemilikan, referensi, dan keadaan setiap halaman RAM

VAD memegang informasi rentang, PTE halaman virtual, dan basis data PFN halaman fisik. Penangan page fault menyilangkan ketiganya untuk memutuskan apakah akses dapat dilanjutkan.

Tiga buku besar dari alamat virtual ke RAM fisikAlamat virtual dikelola VAD pada satuan rentang dan PTE pada satuan halaman virtual, dan basis data PFN menelusuri halaman fisik sasaran terjemahan PTE pada satuan halaman fisikMenilai Reserve/Commit dan proteksiTerjemahan validAlamat virtualVAD (buku besar rentang)PTE (buku besar halaman virtual)Basis data PFN (buku besar halaman fisik)Halaman RAM fisik

Gambar 2: Tiga buku besar dengan granularitas berbeda. Penanganan fault menyilangkan VAD dan PTE, lalu mencerminkan hasilnya di sisi PFN.

Tokoh utama artikel ini adalah VAD dan PTE. Basis data PFN akan dilihat dari sisi halaman fisik di bagian 2.

3. Reserve, Commit, dan Touch adalah peristiwa terpisah

3.1. Reserve — menyisihkan alamat

Pertama, reservasi rentang alamat virtual 256MiB yang kontigu.

void* base = VirtualAlloc(
    nullptr,
    256ull * 1024 * 1024,
    MEM_RESERVE,
    PAGE_NOACCESS);

Yang terjadi pada titik ini hanyalah sebuah alamat disisihkan di ruang virtual proses agar alokasi lain tidak memakai rentang ini. MEM_RESERVE tidak mengalokasikan wilayah penyimpanan fisik di RAM maupun di berkas halaman.1

Karena proses 64-bit punya ruang virtual yang luas, mereservasi rentang besar lebih dulu lalu meng-Commit hanya bagian yang dibutuhkan kemudian menjadi rancangan yang realistis.

3.2. Commit — menjanjikan bahwa isi dapat disimpan

Berikutnya, Commit rentang yang sudah direservasi.

void* committed = VirtualAlloc(
    base,
    256ull * 1024 * 1024,
    MEM_COMMIT,
    PAGE_READWRITE);

Jika berhasil, jumlah yang dijanjikan — yang tercermin di Commit Total sistem, dan biasanya di Private Bytes proses — naik. Meski begitu, 256MiB halaman fisik tidak berbaris sekaligus. Halaman biasa tetap belum dialokasikan secara fisik sampai akses pertama.12

Jadi apa gunanya Commit? Jika sistem tidak dapat menanggung janji itu, kegagalan dapat dikembalikan pada saat Commit, bukan di tengah pemakaian memori.

3.3. Touch — saat halaman fisik menjadi perlu

Akhirnya, penugasan berikut menulis ke halaman pertama untuk pertama kali.

static_cast<unsigned char*>(base)[0] = 1;

CPU mencoba menerjemahkan alamat virtual ke alamat fisik, tetapi PTE belum punya terjemahan valid ke halaman fisik. Page fault terjadi di sini.

Manajer memori yang menerima kendali menilai ini sebagai «akses pertama ke halaman privat yang sudah di-Commit dan dapat ditulis», memperoleh halaman fisik yang sudah nol, mengikatnya ke PTE, dan menambahkannya ke Working Set. Instruksi tulis yang gagal kemudian dijalankan ulang.

Dari aplikasi tampak seperti penugasan biasa, tetapi di dalam kendali masuk kernel di tengah penugasan, halaman fisik dialokasikan, lalu eksekusi kembali ke instruksi yang sama.

4. VAD — buku besar rentang ruang virtual

VAD adalah singkatan Virtual Address Descriptor. Windows mengelola rentang alamat yang dipakai proses sebagai pohon VAD. Perintah !vad di WinDbg menampilkan VPN awal dan akhir, Commit, atribut proteksi, Private/Mapped, Control Area, dan lainnya.3

Informasi representatif yang dicatat VAD mencakup yang berikut.

  • Awal dan akhir rentang alamat
  • Jenis seperti Private, Mapped, atau Image
  • Keadaan Reserve/Commit
  • Proteksi seperti baca, tulis, eksekusi, dan Copy-on-Write
  • Korespondensi ke berkas atau section
  • Atribut khusus seperti guard page

Alasan mengelola per rentang adalah efisiensi. 256MiB setara 65.536 halaman pada 4KiB. Daripada membangun struktur pengelolaan lengkap untuk setiap halaman di muka, lebih hemat menahan «rentang kontigu ini adalah satu reservasi» di VAD dan mewujudkan halaman saat menjadi perlu.

4.1. Menemukan VAD tidak menjamin pemulihan

«Jika ada di VAD, fault terselesaikan; jika tidak, pelanggaran akses» nyaman sebagai pengantar, tetapi terlalu menyederhanakan. Bahkan ketika VAD ditemukan, akses biasa tidak dapat dilanjutkan dalam kasus seperti berikut.

  • Hanya Reserve, dan halaman sasaran belum di-Commit
  • PAGE_NOACCESS
  • Menulis ke halaman hanya-baca
  • Mengeksekusi instruksi dari halaman yang tidak dapat dieksekusi
  • Sentuhan pertama pada guard page
  • Sentuhan di luar rentang valid sebuah section

Sebaliknya, meski PTE tidak valid, jika keadaan perangkat lunak VAD dan PTE menunjukkan akses yang sah, fault dapat diselesaikan sebagai demand-zero, pemulihan Transition, page-in, atau CoW. Secara tepat, jawabannya adalah menilai VAD, PTE, atribut proteksi, dan jenis akses bersama-sama.

5. Tabel halaman dan TLB

Pointer yang dipegang aplikasi adalah alamat virtual. Agar CPU mengakses RAM, nomor halaman virtual harus diterjemahkan menjadi nomor halaman fisik. Tabel terjemahan hierarkis itu adalah tabel halaman, dan entri di ujungnya adalah PTE (Page Table Entry).

PTE yang valid secara konseptual memegang PFN, proteksi baca/tulis/eksekusi, izin mode pengguna, Accessed/Dirty, dan informasi serupa. Tata letak bit sebenarnya bergantung pada CPU dan versi Windows.

Menelusuri tabel halaman setiap kali akan terlalu lambat, jadi CPU menyimpan hasil terjemahan terbaru di TLB (Translation Lookaside Buffer). Terjemahan alamat berjalan dalam urutan ini.

  1. Jika TLB punya terjemahan dan akses cocok dengan proteksinya, hasil itu dipakai.
  2. Jika TLB tidak punya terjemahan, CPU menelusuri tabel halaman.
  3. Jika ada PTE valid dan proteksi juga cocok, terjemahan didaftarkan di TLB dan eksekusi berlanjut.
  4. Jika tidak ada terjemahan valid, atau ada pelanggaran proteksi, kendali masuk ke titik masuk page fault. Pemeriksaan proteksi juga dilakukan ketika terjemahan berasal dari TLB.

Dari alur ini jelas bahwa TLB miss dan page fault adalah hal berbeda. Jika satu-satunya masalah adalah TLB tidak punya terjemahan dan PTE valid, yang terjadi hanyalah penelusuran tabel halaman. Sebaliknya, meski TLB punya terjemahan, pelanggaran proteksi seperti menulis ke halaman hanya-baca atau mengeksekusi instruksi pada halaman yang tidak dapat dieksekusi tetap masuk ke titik masuk page fault. Itulah sebabnya menulis ke halaman CoW dapat memicu fault meski terjemahan sudah di-cache.

Alur terjemahan alamat dan titik masuk page faultMeski TLB punya terjemahan, ketidakcocokan proteksi masuk ke titik masuk page fault. Jika TLB tidak punya terjemahan, tabel halaman ditelusuri; PTE valid yang juga cocok proteksinya didaftarkan di TLB dan eksekusi berlanjut, sedangkan terjemahan tidak valid atau pelanggaran proteksi masuk ke titik masuk page faultAdaCocokPelanggaran proteksiTidakYaTidak valid atau pelanggaran proteksiAkses memoriApakah TLB punya terjemahan?Apakah akses cocok dengan proteksi?Lanjut dengan terjemahan ituKe titik masuk page faultPenelusuran tabel halamanPTE valid dan proteksi juga cocok?Daftarkan di TLB dan lanjut (tanpa fault)

Gambar 3: TLB miss dapat diselesaikan dengan menelusuri tabel halaman. Kendali masuk ke page fault ketika terjemahan tidak valid atau ada pelanggaran proteksi, dan pelanggaran proteksi terjadi bahkan pada TLB hit.

5.1. PTE yang tidak valid bukan sekadar kosong

PTE yang tidak valid pun tidak berarti isinya kosong. Dari keadaan perangkat lunak PTE yang tidak valid, Windows membedakan kasus seperti berikut.

  • Halaman demand-zero yang belum pernah diwujudkan
  • Halaman Transition yang tetap di RAM
  • Halaman bersama yang merujuk Prototype PTE
  • Halaman privat yang disimpan di berkas halaman
  • Pelanggaran proteksi atau wilayah tidak valid

Tugas CPU berhenti pada keputusan «ini bukan terjemahan valid biasa» dan menyerahkannya ke kernel. Pemaknaan selanjutnya dilakukan manajer memori.

6. Page fault dari awal sampai akhir

Mari ikuti penulisan pertama ke halaman privat yang sudah di-Commit dalam enam tahap.

  1. CPU mencoba menulis.
    TLB dan tabel halaman diperiksa, tetapi PTE sasaran tidak punya PFN valid.
  2. CPU menaikkan page fault.
    Alamat virtual yang fault, jenis baca/tulis/eksekusi, pengguna/kernel, serta apakah masalahnya terjemahan hilang atau pelanggaran proteksi diserahkan ke kernel.
  3. Manajer memori memeriksa VAD dan PTE.
    Ia memutuskan apakah halaman sudah di-Commit, apakah proteksi cocok, dan mana dari demand-zero, Transition, bersama, page-in, CoW, atau pengecualian yang berlaku.
  4. Jika demand-zero, halaman fisik yang sudah nol diperoleh.
    Halaman yang baru diserahkan harus bernilai nol agar data proses lain tidak bocor.
  5. Informasi pengelolaan PTE dan PFN diperbarui.
    PFN dan proteksi ditetapkan di PTE, halaman fisik dijadikan Active, dan ditambahkan ke Working Set proses.
  6. Instruksi yang gagal dijalankan ulang.
    Karena fault terselesaikan secara normal, pengecualian mode pengguna tidak disampaikan, dan aplikasi melanjutkan penugasan seperti biasa.

Peristiwa page fault ETW juga mencatat Transition, Demand Zero, Copy-on-Write, Guard Page, Hard Page Fault, dan Access Violation sebagai jenis yang berbeda.4

Jadi page fault bukan kata yang dari awal berarti «kelainan». Itu titik masuk bersama untuk meminta OS memutuskan ketika CPU tidak dapat menerjemahkan di jalur biasa.

Percabangan penyelesaian page faultManajer memori menilai VAD, PTE, atribut proteksi, dan jenis akses, lalu mengirim ke demand-zero, penyambungan ulang halaman yang masih di RAM, hard fault dari backing store, copy-on-write, pemberitahuan guard page, atau pengecualianAkses pertamaMasih di RAMPerlu baca diskTulis CoWGuard pageTidak dapat diselesaikanPage fault terjadiNilai VAD, PTE, proteksi, jenisDemand-zero (soft)Sambung ulang dari Standby (soft)Hard fault (I/O disk)Salin dan tukar PTEHapus guard dan beri tahuPengecualian (0xC0000005 dll.)

Gambar 4: Fault yang masuk lewat titik masuk yang sama terpecah menjadi enam jenis hasil tergantung penilaian. Rincian guard page dibahas di bagian 9.

7. Demand-zero — soft fault yang tidak membaca disk

Demand-zero adalah soft fault representatif yang terjadi ketika halaman privat yang sudah di-Commit disentuh pertama kali. Dokumentasi Working Set Microsoft juga mencantumkan «proses merujuk halaman virtual yang dialokasikan untuk pertama kali» sebagai contoh soft fault.5

Demand-zero punya ciri berikut.

  • Tidak perlu membaca data asli dari disk
  • Isi awal bernilai nol
  • Halaman fisik yang tersedia diikat
  • Working Set dan Page Fault Count kumulatif naik
  • Penanganan ini saja tidak menaikkan Memory\\Pages Input/sec

Itulah sebabnya lonjakan Page Faults/sec tepat setelah startup tidak dengan sendirinya berarti penyimpanan tersumbat.

Kompromi alokasi tertunda juga perlu dirapikan. Jika 256MiB di-Commit dan yang benar-benar dipakai hanya 8MiB, membiarkan 248MiB sisanya di luar RAM masuk akal. Sebagai gantinya, akses pertama membawa biaya penanganan fault. Untuk pekerjaan yang peka latensi ada rancangan yang menyentuh setiap halaman sebelum mulai agar terjadi prefault, tetapi itu kompromi yang menaikkan jumlah RAM yang residen di muka.

8. Soft fault dan hard fault

8.1. Soft fault

Soft fault adalah fault yang dapat diselesaikan tanpa I/O baca ke backing store. Contoh representatif mencakup yang berikut.

  • Demand-zero
  • Penyambungan ulang halaman yang tetap di Standby/Transition
  • Penyambungan halaman bersama yang ada di Working Set proses lain
  • Penyambungan halaman yang sudah di-prefetch
  • Copy-on-Write yang halaman aslinya masih residen

Masih ada biaya CPU untuk transisi kernel, kunci, pembaruan PTE/PFN, koherensi TLB, dan semacamnya, tetapi tidak ada waktu tunggu penyimpanan.5

8.2. Hard fault

Di sisi lain, ketika halaman yang dibutuhkan tidak ada di mana pun di RAM dan harus dibaca dari backing store, itu hard fault. Sumber bacanya bukan hanya berkas halaman.

  • Halaman privat yang ditulis ke berkas halaman
  • Memory-mapped file
  • Image EXE atau DLL
  • Berkas data yang dirujuk cache berkas

Peristiwa ETW HardFault mencakup FileObject, ReadOffset, dan ByteCount, sehingga sumber baca sebenarnya dapat ditelusuri.6

Oleh karena itu Hard Fault = pembacaan pagefile.sys tidak benar.

Ketika baca backing store diperlukan, permintaan masuk ke tumpukan I/O Windows. Alur IRP serta penerbitan/penyelesaian dibahas di «Kedalaman I/O Windows (bagian 1)», dan pertemuan dengan cache berkas di «Kedalaman I/O Windows (bagian 4)». Jika halaman ada di RAM, manajer memori dapat kembali sendiri; jika tidak, I/O diterbitkan dan utas yang fault menunggu sampai selesai.

9. Fault yang tidak dapat diselesaikan menjadi pengecualian

Fault yang, setelah VAD dan PTE diperiksa, tidak dapat diselesaikan sebagai alokasi sah, page-in, atau CoW disampaikan ke mode pengguna sebagai pengecualian.

Kasus representatif adalah STATUS_ACCESS_VIOLATION, kode pengecualian 0xC0000005. Itu terjadi pada baca, tulis, atau eksekusi alamat yang tidak valid; parameter pengecualian pertama menunjukkan jenis akses dan yang kedua alamat yang melanggar.7

Pola khas mencakup yang berikut.

  • Membaca NULL, alamat yang sudah dibebaskan, atau alamat di luar array
  • Menulis ke halaman hanya-baca
  • Mengeksekusi instruksi dari halaman yang dibuat tidak dapat dieksekusi oleh DEP/NX
  • Menyentuh rentang yang direservasi tetapi belum di-Commit

PAGE_GUARD punya makna sedikit berbeda. Itu mekanisme pemberitahuan sekali pakai tentang akses: menaikkan STATUS_GUARD_PAGE_VIOLATION dan dipakai untuk hal seperti pertumbuhan tumpukan.8

Alokasi tertunda yang normal, page-in, CoW, pemberitahuan guard, dan pelanggaran akses akhir semuanya, dari sudut pandang CPU, berkumpul di titik masuk page fault yang sama. Yang memutuskan hasil adalah kombinasi VAD, PTE, atribut proteksi, dan jenis akses.

10. Lihat sendiri

Alur sejauh ini dapat diamati di mesin sendiri. Program C++ berikut mereservasi 256MiB, meng-Commit, menulis satu byte ke setiap halaman, lalu me-Release. Ia menunggu Enter di setiap tahap agar perubahan dapat diamati di VMMap dan PerfMon.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <psapi.h>

#include <cstdio>
#include <cstdlib>

#pragma comment(lib, "Psapi.lib")

constexpr SIZE_T kSize = 256ull * 1024 * 1024;

void PrintMemory(const char* stage)
{
    PROCESS_MEMORY_COUNTERS_EX c{};
    c.cb = sizeof(c);
    if (!GetProcessMemoryInfo(
            GetCurrentProcess(),
            reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&c),
            sizeof(c))) {
        std::printf("GetProcessMemoryInfo failed: %lu\n", GetLastError());
        return;
    }

    std::printf(
        "%-10s WS=%zu MiB  Private=%zu MiB  Faults=%lu\n",
        stage,
        c.WorkingSetSize / 1024 / 1024,
        c.PrivateUsage / 1024 / 1024,
        c.PageFaultCount);
}

void Pause(const char* message)
{
    PrintMemory(message);
    std::puts("Press Enter...");
    (void)std::getchar();
}

int main()
{
    SYSTEM_INFO si{};
    GetSystemInfo(&si);
    std::printf("PID=%lu, page=%lu bytes\n",
                GetCurrentProcessId(), si.dwPageSize);

    void* base = VirtualAlloc(nullptr, kSize, MEM_RESERVE, PAGE_NOACCESS);
    if (!base) {
        std::fprintf(stderr, "Reserve failed: %lu\n", GetLastError());
        return EXIT_FAILURE;
    }
    Pause("reserved");

    if (!VirtualAlloc(base, kSize, MEM_COMMIT, PAGE_READWRITE)) {
        std::fprintf(stderr, "Commit failed: %lu\n", GetLastError());
        VirtualFree(base, 0, MEM_RELEASE);
        return EXIT_FAILURE;
    }
    Pause("committed");

    auto* bytes = static_cast<volatile unsigned char*>(base);
    for (SIZE_T offset = 0; offset < kSize; offset += si.dwPageSize) {
        bytes[offset] = 1;
    }
    Pause("touched");

    if (!VirtualFree(base, 0, MEM_RELEASE)) {
        std::fprintf(stderr, "Release failed: %lu\n", GetLastError());
        return EXIT_FAILURE;
    }
    Pause("released");
}

Dari x64 Native Tools Command Prompt Visual Studio, program ini dapat dibangun dengan perintah berikut.

cl /std:c++20 /EHsc /W4 memory_fault_demo.cpp

10.1. Apa yang dilihat di VMMap

VMMap adalah alat yang menampilkan memori virtual yang direservasi, Commit, Working Set, Private, dan Shareable menurut jenis.9 Perubahan yang diharapkan di setiap tahap adalah sebagai berikut.

Tahap Perubahan yang diharapkan
Reserve Address Space Size naik, tetapi Commit/WS tidak naik sebesar itu
Commit Private Commit naik sekitar 256MiB
Touch Working Set dan Private WS naik substansial, dan Fault Count juga naik
Release Rentang sasaran menghilang, dan Commit serta WS turun

Angka aktual bervariasi menurut runtime, produk keamanan, tekanan memori, dan saat pengamatan. Lihat ke arah mana angka bergerak antartahap, bukan apakah tepat 256MiB.

10.2. Memisahkan soft dan hard di PerfMon

Di PerfMon, letakkan penghitung berikut pada sumbu waktu yang sama.

  • Process(<target>)\\Page Faults/sec
  • Memory\\Pages Input/sec
  • Memory\\Page Reads/sec
  • Memory\\Available MBytes
  • Process(<target>)\\Working Set - Private
  • Process(<target>)\\Private Bytes

Process\\Page Faults/sec mencakup soft fault dan hard fault. Memory\\Pages Input/sec, sebaliknya, adalah jumlah halaman yang dibaca dari disk untuk menyelesaikan hard fault.10

Pada tahap Touch program ini, Page Faults/sec seharusnya melonjak sementara Pages Input/sec tidak naik banyak. Halaman Commit baru diwujudkan oleh demand-zero, jadi data asli tidak perlu dibaca dari disk.

Jika beberapa proses berbagi nama yang sama, nomor PerfMon seperti process#1 dapat berubah antar-restart. Silangkan dengan penghitung yang menampilkan PID, atau identifikasi menurut PID dengan Process V2 atau ETW/WPA.

11. Tiga salah baca yang dihindari dalam praktik

11.1. «Commit naik, jadi ini kebocoran RAM»

Commit adalah jumlah isi yang dijanjikan untuk disimpan; halaman yang belum di-Touch mungkin tidak residen di RAM. Untuk menilai kebocoran, lihat deret waktu Private Bytes, rincian alokasi, dan apakah angka kembali ke garis dasar setelah pemrosesan selesai.

11.2. «Page Faults/sec tinggi, jadi disk lambat»

Soft fault tidak melibatkan I/O disk. Pisahkan Page Faults/sec, Pages Input/sec, dan waktu tunggu penyimpanan; jika perlu, telusuri berkas sumber serta tumpukan dengan peristiwa ETW HardFault.

11.3. «Mengosongkan Working Set akan memperbaiki kebocoran»

Mengeluarkan halaman dari Working Set tidak melepaskan Commit atau kepemilikan. Halaman pindah ke Standby atau Modified dan nanti kembali lewat fault. Memperbaiki kebocoran mensyaratkan pihak yang mengalokasikan melakukan VirtualFree, pembebasan heap, penghancuran objek, dan semacamnya.

Ke mana halaman fisik yang dikeluarkan itu pergi ditelusuri di bagian 2.

12. Ringkasan

  • MEM_RESERVE menyisihkan rentang alamat virtual, tetapi tidak mengalokasikan wilayah fisik di RAM atau berkas halaman.1
  • MEM_COMMIT mengonsumsi Commit dan menjamin isi dapat disimpan di kemudian hari, tetapi halaman fisik biasa belum dialokasikan sampai akses pertama.12
  • VAD adalah buku besar rentang, PTE buku besar halaman virtual, dan basis data PFN buku besar halaman fisik.
  • TLB miss bukan page fault. Jika PTE valid, penelusuran tabel halaman saja menyelesaikannya.
  • Demand-zero, pemulihan Transition, dan penyambungan halaman bersama adalah soft fault yang dapat diselesaikan tanpa I/O disk.5
  • Jika baca dari berkas halaman, DLL, EXE, atau berkas yang dipetakan diperlukan, itu hard fault.6
  • Jika pemeriksaan VAD, PTE, dan atribut proteksi tidak dapat menyelesaikan fault, pengecualian seperti 0xC0000005 muncul.7
  • Untuk penilaian kinerja, jangan melihat Page Faults/sec saja; lihat Pages Input/sec, Available, Working Set, Private Bytes, dan waktu tunggu penyimpanan pada sumbu waktu yang sama.

Bersambung di bagian 2, «Hidup sebuah halaman fisik: lima daftar dan kebenaran berkas halaman».

Setelah janji Commit dijadikan halaman fisik, artikel itu menelusuri ke mana halaman itu pergi ketika meninggalkan Working Set, dari basis data PFN dan daftar halaman.

Artikel terkait

Area konsultasi terkait

KomuraSoft LLC menangani investigasi pemakaian memori aplikasi Windows, pelanggaran akses, keterlambatan startup, paging, dan cacat kode native.

Tautan referensi

  1. Microsoft Learn, VirtualAlloc function. Tentang MEM_RESERVE mereservasi rentang alamat virtual tanpa mengalokasikan penyimpanan fisik; MEM_COMMIT membebankan commit charge terhadap memori dan berkas halaman sistem secara keseluruhan; isi awal halaman yang sudah di-Commit bernilai nol; dan halaman fisik sebenarnya belum dialokasikan sampai diakses. ↩ ↩2 ↩3 ↩4 ↩5 ↩6

  2. Microsoft Learn, PERFORMANCE_INFORMATION structure. Tentang CommitTotal sebagai jumlah halaman Commit sistem saat ini, dan CommitLimit sebagai batas atas yang dapat di-Commit tanpa memperluas berkas halaman. ↩ ↩2

  3. Microsoft Learn, !vad (WinDbg). Tentang !vad menampilkan pohon VAD dan memungkinkan memeriksa VPN awal dan akhir, Commit, Mapped/Private, atribut proteksi, Control Area, dan lainnya. ↩

  4. Microsoft Learn, PageFault_TypeGroup1 class. Tentang ETW membedakan dan mencatat Transition Fault, Demand Zero Fault, Copy-on-Write, Guard Page Fault, Hard Page Fault, dan Access Violation. ↩

  5. Microsoft Learn, Working Set. Tentang soft fault yang dapat diselesaikan tanpa mengakses backing store, dan terjadi dari Working Set proses lain, Transition, demand-zero pada referensi pertama, dan semacamnya. ↩ ↩2 ↩3

  6. Microsoft Learn, PageFault_HardFault class. Tentang peristiwa HardFault yang mencakup FileObject, ReadOffset, ByteCount, VirtualAddress, dan Thread ID, sehingga sumber baca dapat ditelusuri. ↩ ↩2

  7. Microsoft Learn, Access Violation C0000005. Tentang 0xC0000005 yang terjadi pada baca, tulis, atau eksekusi alamat memori yang tidak valid, dan parameter pengecualian menunjukkan jenis akses serta alamat yang melanggar. ↩ ↩2

  8. Microsoft Learn, Creating Guard Pages. Tentang PAGE_GUARD yang menyediakan pemberitahuan sekali pakai tentang akses halaman dan menaikkan STATUS_GUARD_PAGE_VIOLATION. ↩

  9. Microsoft Learn, VMMap - Sysinternals. Tentang VMMap merinci memori virtual yang di-Commit menurut jenis dan menampilkan Working Set setiap jenis serta peta alamat terperinci. ↩

  10. Microsoft Learn, Performance Analysis of Logs (PAL) Tool. Tentang Memory\\Pages Input/sec sebagai jumlah halaman yang dibaca dari disk untuk menyelesaikan hard page fault. ↩

Artikel terbaru dengan tag yang sama untuk mendalami topik-topik terdekat.

Halaman-halaman ini menempatkan topik dalam konteks layanan dan keputusan yang lebih luas.

Artikel ini berkaitan langsung dengan layanan berikut.

Pertanyaan yang sering diajukan

Pertanyaan yang sering muncul dalam konsultasi tentang topik artikel ini.

Apakah RAM sudah dialokasikan saat MEM_COMMIT diserahkan ke VirtualAlloc?
Pada memori privat biasa, Commit mengonsumsi headroom commit sistem, tetapi halaman fisik yang sesuai belum dialokasikan sampai akses pertama. Halaman yang pertama kali disentuh lewat penulisan memperoleh halaman fisik selama penanganan demand-zero fault.
Apakah page fault berarti ada kelainan atau masalah kinerja?
Tidak. Soft fault tanpa I/O disk — misalnya demand-zero atau pengembalian dari Standby — adalah operasi normal. Untuk menilai kinerja, jangan hanya melihat Page Faults/sec; sertakan juga Pages Input/sec, waktu tunggu penyimpanan, dan Available MBytes.
Apakah TLB miss sama dengan page fault?
Berbeda. Jika TLB tidak punya hasil terjemahan tetapi PTE di tabel halaman valid, CPU hanya menelusuri tabel dan mendaftarkan ulang terjemahan. Kendali masuk ke page fault ketika PTE tidak valid atau ada pelanggaran proteksi.
Jika rentang alamat ada di VAD, apakah pelanggaran akses mustahil?
Tidak selalu. Selain ada-tidaknya VAD, manajer memori menilai Reserve versus Commit, proteksi baca/tulis/eksekusi, guard page, keadaan PTE, dan lainnya. Jika fault tidak dapat diselesaikan, pengecualian seperti 0xC0000005 muncul.
Apakah Page Faults/sec yang tinggi berarti RAM kurang?
Dari itu saja tidak dapat disimpulkan. Page Faults/sec juga mencakup banyak soft fault. Angka itu perlu dikorelasikan pada sumbu waktu yang sama dengan Memory\Pages Input/sec, Memory\Page Reads/sec, Available MBytes, dan waktu tunggu disk.

Profil penulis

Halaman perkenalan penulis artikel.

Go Komura

Direktur KomuraSoft LLC

Berspesialisasi dalam pengembangan perangkat lunak Windows, konsultasi teknis, dan investigasi bug, terutama pada proyek dengan sistem yang sudah ada dan bug yang sulit direproduksi.

Kembali ke blog