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

· · Windows, Manajemen memori, VirtualAlloc, Page fault, VAD, Pemantauan kinerja

Menyerahkan MEM_COMMIT ke VirtualAlloc menaikkan Commit saat itu juga. Working Set, namun, tidak selalu naik sebesar yang sama. Jadi di mana memori yang Anda kira sudah dialokasikan?

Jawabannya: sebagian besar halaman belum punya RAM fisik yang sesuai. Windows menunda penetapan 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 mengikuti jalan yang dilalui «byte pertama yang Anda sentuh» sampai mencapai RAM fisik. Jika Anda ingin merapikan dulu makna angka seperti Working Set dan Commit, lihat artikel pengantar «What Does Windows’ “Memory Usage” Actually Mean? — Correctly Reading Working Set, Private Bytes, Commit, and the Page File». Serial ini tidak mendefinisikan ulang istilah yang dipakai di sana; ia menggali dari sisi mekanisme «mengapa angkanya keluar seperti itu».

«Kedalaman memori Windows» — ketiga bagian

  1. Bagian 1 (artikel ini): alamat virtual dan page fault
    Kita mengikuti kapan wilayah yang dialokasikan dengan VirtualAlloc memperoleh RAM fisik.
  2. Bagian 2: kehidupan sebuah halaman fisik
    Kita mengikuti bagaimana halaman yang meninggalkan Working Set bergerak melalui Modified, Standby, Free, dan Zeroed.
  3. Bagian 3: objek section dan copy-on-write
    Kita mengikuti 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, penggunaan memori aplikasi Windows, page fault tepat setelah startup, 0xC0000005, dan angka di VMMap serta PerfMon. Prasyarat adalah Windows 10/11 atau Windows Server terkini, dan latar yang dibutuhkan adalah pointer serta dasar VirtualAlloc; pengalaman tata letak bit tabel halaman atau debugger kernel tidak diperlukan. Tingkat kesulitannya menengah. Kita memakai nama struktur internal, tetapi tidak mengasumsikan tata letak tidak terdokumentasi yang bergantung pada build Windows tertentu.

1. Kesimpulan dulu

Alur memori privat biasa, dalam satu baris, adalah ini.

Reserve menyisihkan rentang alamat virtual, Commit memperhitungkan commit charge terhadap batas commit untuk menjamin tempat masa depan menyimpan isi, dan page fault pada akses pertama menetapkan halaman fisik.

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

Meski begitu, tidak akurat juga mengklaim bahwa «Reserve/Commit hanya menulis ke VAD». Dalam praktik, Reserve terutama membuat VAD yang merepresentasikan rentang alamat virtual dan atributnya, dan Commit menaikkan Commit Total sistem serta mencatat keadaan commit rentang itu. Tingkat tabel halaman perantara dan PTE individual dibangun secara malas saat dibutuhkan, dan pengikatan akhir ke RAM fisik biasanya terjadi pada akses pertama.

Commit bukan janji kosong; itu janji se-sistem bahwa isi dapat disimpan di masa depan 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 menetapkan halaman fisik dan menambahkannya ke Working Set1. MEM_RESERVE2. MEM_COMMIT3. Akses pertama(Touch)Catat rentang dan atribut di VADKonsumsi Commit Total(belum ada halaman fisik)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 diikat hanya pada langkah terakhir, akses pertama.

2. Tiga buku besar yang menelusuri halaman virtual

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

Buku besar Satuan Peran
VAD Rentang alamat virtual Mengelola apa wilayah itu, 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 tentang rentang, PTE tentang halaman virtual, dan basis data PFN tentang halaman fisik. Penangan page fault menyilangkan ini untuk memutuskan apakah akses dapat dilanjutkan.

Tiga buku besar dari alamat virtual ke RAM fisikAlamat virtual dikelola VAD pada granularitas rentang dan PTE pada granularitas halaman virtual, dan basis data PFN menelusuri halaman fisik yang menjadi sasaran terjemahan PTE pada granularitas halaman fisikNilai 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.

Bintang artikel ini adalah VAD dan PTE. Kita akan melihat basis data PFN dari sisi halaman fisik di Bagian 2.

3. Reserve, Commit, dan Touch adalah peristiwa terpisah

3.1. Reserve — mengklaim sebuah alamat

Pertama, reservasi rentang alamat virtual 256MiB yang berkesinambungan.

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 dapat memakai rentang ini. MEM_RESERVE tidak menetapkan penyimpanan fisik di RAM maupun di berkas halaman.1

Karena proses 64-bit punya ruang virtual yang luas, menjadi praktis untuk Reserve rentang besar dulu dan Commit hanya bagian yang dibutuhkan kemudian.

3.2. Commit — menjanjikan bahwa itu 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 ditetapkan secara fisik sampai akses pertama.12

Jadi apa gunanya Commit? Bahwa ketika sistem tidak dapat menanggung janji itu, ia dapat mengembalikan kegagalan pada waktu Commit, bukan di tengah pemakaian memori.

3.3. Touch — ketika 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. Ia lalu menjalankan ulang instruksi tulis yang gagal.

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

4. VAD — buku besar rentang ruang virtual

VAD adalah singkatan Virtual Address Descriptor, dan Windows mengelola rentang alamat yang dipakai proses sebagai pohon VAD. Dengan perintah !vad WinDbg Anda dapat memeriksa 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 adalah 65.536 halaman pada 4KiB. Daripada membangun struktur pengelolaan lengkap untuk setiap halaman di muka, lebih hemat menahan «rentang berkesinambungan 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, Anda mendapat pelanggaran akses» adalah penjelasan tingkat awal yang nyaman, 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
  • Tulis ke halaman hanya-baca
  • Eksekusi 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, itu dapat diselesaikan sebagai demand-zero, pemulihan Transition, page-in, atau CoW. Lebih tepat, jawabannya adalah nilai 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, ia harus menerjemahkan nomor halaman virtual menjadi nomor halaman fisik. Tabel terjemahan hierarkis itu adalah tabel halaman, dan entri daunnya 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 terjemahan terbaru di TLB (Translation Lookaside Buffer). Terjemahan alamat berjalan dalam urutan ini.

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

Seperti ditunjukkan alur ini, TLB miss dan page fault adalah hal yang 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 tulis ke halaman hanya-baca atau eksekusi instruksi pada halaman yang tidak dapat dieksekusi berlanjut ke titik masuk page fault. Itulah mengapa tulis ke halaman CoW dapat fault meski terjemahan sudah tersimpan.

Alur terjemahan alamat dan titik masuk page faultMeski TLB punya terjemahan, ketidakcocokan proteksi berlanjut ke titik masuk page fault. Jika TLB tidak punya terjemahan tabel halaman ditelusuri; PTE valid yang juga cocok proteksi didaftarkan di TLB dan eksekusi berlanjut, dan terjemahan tidak valid atau pelanggaran proteksi berlanjut ke titik masuk page faultYaCocokPelanggaran 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 berlanjut 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

Bahkan PTE yang tidak valid tidak 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 hanyalah memutuskan «ini bukan terjemahan valid biasa» dan menyerahkannya ke kernel; manajer memori yang memberi makna dari situ.

6. Page fault dari awal sampai akhir

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

  1. CPU mencoba menulis.
    Ia memeriksa TLB dan tabel halaman, tetapi PTE sasaran tidak punya PFN valid.
  2. CPU menaikkan page fault.
    Ia menyerahkan alamat virtual yang fault, jenis baca/tulis/eksekusi, pengguna/kernel, dan apakah masalahnya terjemahan hilang atau pelanggaran proteksi 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 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, tidak ada pengecualian mode pengguna yang disampaikan, dan aplikasi melanjutkan penugasan seperti biasa.

Peristiwa ETW page fault 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 berarti «tidak normal» dari awal. 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, menyambung 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(lunak)Sambung ulang dari Standby(lunak)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 adalah nol
  • Halaman fisik yang tersedia diikat
  • Working Set dan Page Fault Count kumulatif naik
  • Penanganan ini saja tidak menaikkan Memory\\Pages Input/sec

Itulah mengapa lonjakan Page Faults/sec tepat setelah startup tidak dengan sendirinya berarti penyimpanan adalah hambatan.

Kompromi alokasi malas juga layak dirapikan. Jika Anda Commit 256MiB dan benar-benar memakai 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 prefault, tetapi itu kompromi yang menaikkan residensi RAM di depan.

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
  • Menyambung ulang halaman yang tetap di Standby/Transition
  • Menyambungkan halaman bersama yang ada di Working Set proses lain
  • Menyambungkan halaman yang sudah di-prefetch
  • Copy-on-Write yang halaman aslinya residensial

Masih ada biaya CPU untuk transisi kernel, kunci, pembaruan PTE/PFN, koherensi TLB, dan semacamnya, tetapi tidak ada 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 baca bukan hanya berkas halaman.

  • Halaman privat yang ditulis ke berkas halaman
  • Berkas yang dipetakan ke memori
  • Citra EXE atau DLL
  • Berkas data yang dirujuk cache berkas

Peristiwa ETW HardFault mencakup FileObject, ReadOffset, dan ByteCount, jadi Anda dapat menelusuri sumber baca sebenarnya.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 dan penerbitan/penyelesaian dibahas di «The Depths of Windows I/O (Part 1)», dan persimpangan dengan cache berkas di «The Depths of Windows I/O (Part 4)». Jika halaman ada di RAM manajer memori dapat kembali sendiri; jika tidak, ia menerbitkan I/O dan menunggu utas yang fault sampai selesai.

9. Fault yang tidak dapat diselesaikan menjadi pengecualian

Fault yang, setelah memeriksa VAD dan PTE, 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 pemberitahuan sekali pakai tentang akses: ia menaikkan STATUS_GUARD_PAGE_VIOLATION dan dipakai untuk hal seperti pertumbuhan tumpukan.8

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

10. Lihat sendiri

Anda dapat mengamati alur sejauh ini di mesin Anda sendiri. Program C++ berikut Reserve 256MiB, Commit, menulis satu byte ke setiap halaman, dan akhirnya Release. Ia menunggu Enter di setiap tahap agar Anda dapat mengamati perubahan 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, Anda dapat membangun 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 yang sama
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 dengan runtime, produk keamanan, tekanan memori, dan kapan Anda mengamati. Lihat ke arah mana angka bergerak antartahap, bukan apakah tepat 256MiB.

10.2. Memisahkan lunak dan keras 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 yang baru di-Commit diwujudkan oleh demand-zero, jadi tidak perlu membaca data asli dari disk.

Ketika 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 disentuh mungkin tidak residensial 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 tunggu penyimpanan, dan jika perlu ikuti 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 fault kembali. Memperbaiki kebocoran mensyaratkan allocator melakukan VirtualFree, pembebasan heap, penghancuran objek, dan semacamnya.

Ke mana halaman fisik yang dikeluarkan itu pergi adalah yang kita ikuti di Bagian 2.

12. Ringkasan

  • MEM_RESERVE menyisihkan rentang alamat virtual tetapi tidak menetapkan wilayah fisik di RAM atau berkas halaman.1
  • MEM_COMMIT mengonsumsi Commit dan menjamin isi dapat disimpan di masa depan, tetapi halaman fisik biasa tidak ditetapkan 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 menyambungkan 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, Anda mendapat pengecualian seperti 0xC0000005.7
  • Untuk penilaian kinerja, jangan lihat Page Faults/sec saja; lihat Pages Input/sec, Available, Working Set, Private Bytes, dan tunggu penyimpanan pada sumbu waktu yang sama.

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

Setelah janji Commit dijadikan halaman fisik, kita mengikuti 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 penggunaan 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 menetapkan penyimpanan fisik; MEM_COMMIT memperhitungkan commit charge terhadap memori dan berkas halaman sistem; isi awal halaman yang di-Commit adalah nol; dan halaman fisik sebenarnya tidak ditetapkan sampai diakses.  2 3 4 5 6

  2. Microsoft Learn, PERFORMANCE_INFORMATION structure. Tentang CommitTotal adalah jumlah halaman Commit sistem saat ini, dan CommitLimit adalah 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 dapat diselesaikan tanpa mengakses backing store, dan terjadi dari Working Set proses lain, Transition, demand-zero referensi pertama, dan semacamnya.  2 3

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

  7. Microsoft Learn, Access Violation C0000005. Tentang 0xC0000005 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 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 adalah 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 menyerahkan MEM_COMMIT ke VirtualAlloc mengalokasikan RAM saat itu juga?
Di memori privat biasa, Commit mengonsumsi ruang commit sistem, tetapi halaman fisik yang sesuai belum ditetapkan sampai akses pertama. Halaman yang pertama kali disentuh lewat tulis memperoleh halaman fisiknya selama penanganan demand-zero fault.
Apakah page fault berarti ada yang salah atau ada masalah kinerja?
Tidak. Soft fault tanpa I/O disk — seperti demand-zero atau mengembalikan halaman dari Standby — adalah operasi normal. Untuk menilai kinerja, lihat bukan hanya Page Faults/sec tetapi juga Pages Input/sec, tunggu penyimpanan, dan Available MBytes.
Apakah TLB miss dan page fault itu sama?
Berbeda. Meski TLB tidak punya terjemahan, jika PTE tabel halaman valid CPU hanya menelusuri tabel dan mendaftarkan ulang terjemahan. Ia berlanjut ke titik masuk page fault ketika PTE tidak valid atau ada pelanggaran proteksi.
Jika rentang alamat ada di VAD, tidak mungkin mendapat pelanggaran akses?
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 bisa diselesaikan, Anda mendapat pengecualian seperti 0xC0000005.
Apakah Page Faults/sec yang tinggi berarti sistem kekurangan RAM?
Dari itu saja tidak bisa disimpulkan. Page Faults/sec juga mencakup banyak soft fault. Anda perlu mengorelasikannya 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