Informasi Sistem ini berasal dari Process Explorer. Masih ada memori fisik yang tersedia tetapi sistem menunjukkan hampir tidak ada RAM yang tersisa.
Task Manager juga menunjukkan bahwa sekitar 74% dari total RAM digunakan.
Sejak menginstal Windows 8.1, komputer memiliki 4 + 8 = 12 GB RAM. Saya memutakhirkannya dengan mengubah modul 4 GB menjadi 8 GB. Mungkinkah itu masalahnya? Atau apakah perilaku ini normal dan saya baru saja salah mengerti arti memori fisik yang tersedia?
Ctrl+G
pintasan sehingga Stack Exchange dapat mencegahnya membusuk seiring waktu.Jawaban:
Jawaban singkat
Munculan "kehabisan memori" mengatakan bahwa Anda kehabisan batas memori yang dikomit pribadi — jenis memori virtual. Bukan berarti Anda kehabisan RAM (memori fisik). Tidak masalah berapa banyak RAM yang tersedia yang Anda miliki. Memiliki banyak RAM yang Tersedia tidak memungkinkan Anda untuk melebihi batas komit. Batas komit adalah jumlah total RAM Anda (apakah digunakan atau tidak!) Ditambah ukuran pagefile Anda saat ini.
Sebaliknya, batasan komit "habis" (yang sebagian besar merupakan penciptaan ruang alamat virtual private-proses) tidak harus menggunakan RAM apa pun! Tetapi OS tidak akan mengizinkan pembuatannya kecuali ia tahu ada tempat untuk menyimpannya jika perlu. Jadi, Anda dapat mengalami batas komit tanpa menggunakan semua RAM Anda, atau bahkan sebagian besar RAM Anda.
Inilah sebabnya mengapa Anda tidak harus menjalankan tanpa pagefile. Perhatikan bahwa pagefile sebenarnya tidak pernah ditulis untuk! Tapi itu masih akan membiarkan Anda menghindari kesalahan "kehabisan memori" dan "kehabisan memori".
Jawaban Menengah
Windows sebenarnya tidak memiliki pesan kesalahan karena kehabisan RAM. Apa yang Anda kehabisan adalah "komit batas".
Grafik "Sistem" di versi Process Explorer itu tidak disebutkan namanya. Itu harus diberi label "biaya komit". (Dalam versi yang saya miliki itu disebut "System commit". Lebih baik, tetapi masih tidak sepenuhnya konsisten.) Dalam hal apapun, ketinggian "saat ini" dari grafik ada yang menunjukkan lebih rendah di bagian teks sebagai "Biaya Komit" - " Saat ini ", dan ketinggian maksimal grafik menunjukkan" Biaya Komit "-" Batas ".
"Biaya komit" mengacu pada ruang alamat virtual yang didukung oleh pagefile (jika Anda memilikinya) - dengan kata lain, jika tidak semua bisa masuk dalam RAM, sisanya masuk dalam pagefile. (Ada jenis lain dari vas yang didukung oleh file lain - yang disebut vas "dipetakan" - atau yang harus tetap di RAM sepanjang waktu; yang terakhir disebut "tidak dapat dicetak".) "Batas komit" adalah maksimum yang "biaya komit" dapat berupa. Itu sama dengan ukuran RAM Anda plus ukuran pagefile.
Anda tampaknya tidak memiliki pagefile (saya tahu karena batas komit Anda sama dengan ukuran RAM Anda), jadi batas komit hanyalah ukuran RAM.
Rupanya berbagai program + OS telah menggunakan hampir semua komit maksimum yang mungkin.
Ini tidak ada hubungannya langsung dengan berapa banyak RAM yang gratis atau tersedia. Ya, Anda memiliki sekitar 4,5 GB RAM yang tersedia. Itu tidak berarti Anda dapat melebihi batas komit. Memori yang dikomit tidak harus menggunakan RAM dan tidak dibatasi oleh jumlah RAM yang tersedia.
Anda perlu mengaktifkan kembali pagefile - dengan menggunakan banyak komitmen ini, saya akan menyarankan pagefile 16 GB, karena Anda tidak ingin memaksakan OS untuk menyimpan begitu banyak hal dalam RAM, dan pagefile bekerja paling baik jika itu memiliki banyak ruang gratis - atau tambahkan lebih banyak RAM. Lebih banyak lagi. Untuk kinerja yang baik, Anda perlu memiliki banyak ruang dalam RAM untuk kode dan hal-hal lain yang tidak didukung oleh pagefile (tetapi dapat dipindahkan ke file lain).
Jawaban yang Sangat Panjang
(tapi masih jauh lebih pendek daripada bab manajemen memori Windows Internal ...)
Misalkan suatu program mengalokasikan 100 MB memori virtual proses-pribadi. Ini dilakukan dengan panggilan VirtualAlloc dengan opsi "komit". Ini akan menghasilkan peningkatan 100 MB dalam "Biaya komit". Tetapi "alokasi" ini sebenarnya tidak menggunakan RAM apa pun! RAM hanya digunakan ketika beberapa ruang alamat virtual yang baru dikomit diakses untuk pertama kalinya.
Bagaimana RAM akhirnya terbiasa
(jika pernah)
Akses pertama kali ke ruang yang baru dikomit akan hampir selalu menjadi penulisan memori (membaca vas pribadi yang baru dialokasikan sebelum menulis itu hampir selalu merupakan kesalahan pemrograman, karena konten awalnya, tegasnya, tidak terdefinisi). Tapi baca atau tulis, hasilnya, pertama kali Anda menyentuh halaman vas yang baru dialokasikan, adalah kesalahan halaman . Meskipun kata "kesalahan" terdengar buruk, kesalahan halaman adalah peristiwa yang sepenuhnya diharapkan dan bahkan diperlukan dalam OS memori virtual.
Menanggapi jenis kesalahan halaman khusus ini, pager (bagian dari manajer memori OS, yang kadang-kadang saya sebut sebagai "Mm") akan:
Setelah itu kode yang melakukan referensi memori akan menjalankan kembali instruksi yang menimbulkan kesalahan halaman, dan kali ini referensi akan berhasil.
Kami mengatakan bahwa halaman tersebut telah "disalahgunakan" ke dalam set proses yang bekerja, dan ke dalam RAM. Dalam Task Manager ini akan muncul sebagai peningkatan satu halaman (4 KB) dalam "set kerja pribadi" dari proses. Dan pengurangan satu halaman dalam memori fisik yang tersedia. (Yang terakhir mungkin sulit untuk diperhatikan pada mesin yang sibuk.)
Catatan 1: Kesalahan halaman ini tidak melibatkan apa pun yang dibaca dari disk. Halaman yang tidak pernah diakses sebelumnya dari memori virtual berkomitmen tidak memulai kehidupan di disk; ia tidak memiliki tempat pada disk untuk membacanya dari . Ini hanya "terwujud" di halaman RAM yang sebelumnya tersedia. Secara statistik, pada kenyataannya, sebagian besar kesalahan halaman diselesaikan dalam RAM, baik untuk halaman bersama yang sudah ada dalam RAM untuk proses lain, atau ke cache halaman - daftar siaga atau yang dimodifikasi, atau sebagai halaman "permintaan nol" seperti ini.
Catatan 2: Ini hanya membutuhkan satu halaman, 4096 byte, dari "Tersedia". Ruang alamat yang tidak pernah disentuh sebelum dilakukan biasanya disadari — disalahi — hanya satu halaman pada satu waktu, karena setiap halaman "disentuh" untuk pertama kalinya. Tidak akan ada peningkatan, tidak ada keuntungan, dalam melakukan lebih banyak sekaligus; hanya akan memakan waktu n kali lebih lama. Sebaliknya, ketika halaman harus dibaca dari disk, sejumlah "readahead" dicoba karena sebagian besar waktu dalam disk baca adalah dalam overhead operasi, bukan transfer data yang sebenarnya. Jumlah "berkomitmen" tetap pada 100 MB; fakta bahwa satu atau halaman telah rusak tidak mengurangi biaya komit.
Catatan 3:Anggaplah kita memiliki RAM "tersedia" 4 GB. Itu berarti bahwa kita dapat merujuk memori yang sudah dialokasikan tetapi tidak pernah direferensikan sekitar satu juta kali lebih banyak (4 GB / 4096) sebelum kita kehabisan RAM. Pada titik itu, jika kita memiliki file halaman seperti yang dimaksudkan oleh David Cutler dan Lou Perazzoli, beberapa halaman yang paling lama direferensikan dalam RAM akan disimpan pada disk dan kemudian dibuat tersedia untuk digunakan dalam menyelesaikan kesalahan halaman yang lebih baru. (Sebenarnya OS akan memulai metode reklamasi RAM seperti "working set trimming" daripada sebelumnya, dan penulisan aktual ke pagefile di-cache dan di-batch pada daftar halaman yang dimodifikasi untuk efisiensi, dan dan ...) Tidak ada yang akan mempengaruhi "berkomitmen" dihitung. Namun, ini relevan dengan "batas komit". Jika tidak ada ruang untuk semua "
Dan itu terus terjadi ...
Tapi mari kita anggap kita belum melakukan jutaan referensi lagi dan masih ada sekitar 4GB senilai halaman "tersedia". Sekarang mari kita anggap proses yang sama - atau yang lain, tidak masalah - lakukan VirtualAlloc lain, kali ini dikatakan 200 MB. Sekali lagi, 200 MB ini ditambahkan ke biaya komit, dan itu tidak menghapus RAM dari yang tersedia. Cukup ruang alamat VirtualAlloc'ating tidak menggunakan jumlah RAM yang sesuai, dan memiliki RAM "tersedia" yang rendah tidak membatasi jumlah ruang alamat yang Anda dapat VirtualAlloc (juga tidak memiliki RAM tinggi yang tersedia, meningkatkannya).
(Baiklah, ok ... ada sedikit overhead, berjumlah satu (pageable!) Halaman yang digunakan untuk tabel halaman untuk setiap 2 MB (4 MB jika Anda menggunakan sistem x86, non-PAE) dari ruang alamat virtual yang dialokasikan, dan ada "deskriptor alamat virtual" dari beberapa puluh byte untuk setiap rentang yang dialokasikan secara berdekatan.)
Dengan cara ini dimungkinkan - dan umum! - Untuk menggunakan banyak "biaya komit" sementara hanya menggunakan sejumlah kecil RAM.
Jadi, jika "melakukan" ruang alamat virtual tidak menggunakan RAM, mengapa harus ada batasan?
Karena "biaya komit" memang mewakili potensi penggunaan ruang penyimpanan di masa depan . "Batas komit" mewakili jumlah total penyimpanan (ruang RAM + pagefile) yang tersedia untuk menampung alokasi tersebut, jika benar-benar direferensikan dan karenanya perlu disimpan di suatu tempat.
Ketika Mm menyetujui permintaan VirtualAlloc, itu menjanjikan - "membuat komitmen" - bahwa semua memori berikutnya mengakses ke area yang dialokasikan akan berhasil; mereka dapat mengakibatkan kesalahan halaman tetapi kesalahan semua akan dapat diselesaikan, karena ada penyimpanan yang memadai untuk menjaga isi dari semua halaman tersebut, baik dalam RAM atau di pagefile. Mm mengetahui hal ini karena mengetahui berapa banyak ruang penyimpanan yang ada (batas komit) dan berapa banyak yang telah "dikomit" (biaya komit saat ini).
(Tetapi semua halaman itu belum tentu diakses, jadi belum tentu ada penyimpanan aktual dengan jumlah yang dikomit, pada waktu tertentu.)
Jadi ... Bagaimana dengan "sistem kehabisan memori"?
Jika Anda mencoba ke VirtualAlloc dan biaya komit saat ini ditambah ukuran alokasi yang diminta akan membawa Anda melebihi batas komit, DAN OS tidak dapat memperluas pagefile sehingga untuk meningkatkan batas komit ... Anda mendapatkan jendela "kehabisan memori" dan proses melihat panggilan VirtualAlloc FAIL. Sebagian besar program hanya akan mengangkat tangan mereka dan mati pada saat itu. Beberapa akan membabi buta menekan, dengan anggapan bahwa panggilan berhasil, dan gagal kemudian ketika mereka mencoba untuk referensi wilayah yang mereka pikir mereka alokasikan.
Sekali lagi (maaf untuk pengulangan): tidak masalah berapa banyak RAM yang Anda miliki. OS telah berjanji bahwa ruang RAM atau pagefile akan tersedia saat dibutuhkan, tetapi janji itu tidak mengurangi dari "Available". RAM yang tersedia hanya digunakan oleh vm yang berkomitmen ketika direferensikan untuk pertama kalinya, yang menyebabkannya "rusak" ... yaitu direalisasikan dalam memori fisik. Dan hanya melakukan (= mengalokasikan) memori virtual tidak melakukan itu. Hanya membutuhkan ruang alamat virtual gratis dan membuat ruang alamat virtual dapat digunakan darinya.
Tetapi dalam kasus "kehabisan memori" ada permintaan alokasi untuk memori yang dikomit, dan OS telah menambahkan biaya komit saat ini ke ukuran permintaan baru ini ... dan menemukan bahwa total lebih dari batas komit. Jadi jika OS menyetujui yang baru ini, dan semua ruang yang direferensikan setelah itu, tidak akan ada tempat nyata (RAM + pagefile) untuk menyimpan semuanya.
OS tidak akan mengizinkan ini. Ini tidak akan membiarkan lebih banyak vas dialokasikan daripada memiliki ruang untuk menyimpannya dalam kasus terburuk - bahkan jika semuanya "salah". Itulah tujuan dari "komit batas".
Saya katakan tiga kali saya katakan tiga kali saya katakan tiga kali: Jumlah "Tersedia" RAM tidak masalah. Bahwa ruang virtual yang berkomitmen sebenarnya tidak menggunakan semua ruang penyimpanan itu, tidak masalah. Windows tidak dapat "berkomitmen" ke alokasi virtual kecuali jika '' dapat '' semuanya rusak di masa mendatang.
Perhatikan ada jenis lain dari vas yang disebut "dipetakan", terutama digunakan untuk kode dan untuk akses ke file data besar, tetapi tidak dikenakan biaya untuk "biaya komit" dan tidak dibatasi oleh "komit batas". Ini karena ia datang dengan area penyimpanannya sendiri, file-file yang "dipetakan" ke sana. Satu-satunya batasan pada vas "yang dipetakan" adalah jumlah ruang disk yang Anda miliki untuk file yang dipetakan, dan jumlah vas bebas dalam proses Anda untuk memetakannya.
Tetapi ketika saya melihat sistem, saya belum cukup pada batas komit?
Itu pada dasarnya masalah pengukuran dan pencatatan. Anda sedang melihat sistem setelah panggilan VirtualAlloc sudah dicoba dan gagal.
Misalkan Anda hanya memiliki 500 MB batas komit yang tersisa dan beberapa program telah mencoba untuk VirtualAlloc 600 MB. Upaya itu gagal. Kemudian Anda melihat sistem dan berkata, "Apa? Masih ada 500 MB tersisa!" Bahkan mungkin ada banyak lagi yang tersisa pada saat itu, karena proses yang dimaksud kemungkinan sudah benar-benar hilang pada saat itu, sehingga SEMUA dari memori yang dialokasikan sebelumnya telah dialokasikan.
Masalahnya adalah bahwa Anda tidak dapat melihat kembali waktu dan melihat apa yang komit biaya adalah pada saat upaya alokasi dibuat. Dan Anda juga tidak tahu berapa banyak ruang untuk usaha itu. Jadi, Anda tidak dapat melihat secara pasti mengapa upaya itu gagal, atau berapa banyak "batas komit" yang diperlukan untuk memungkinkannya bekerja.
Saya telah melihat "sistem kehabisan memori". Apa itu?
Jika dalam kasus di atas OS DAPAT memperluas pagefile (yaitu Anda membiarkannya pada pengaturan "sistem yang dikelola" default, atau Anda mengelolanya tetapi Anda mengatur maksimum menjadi lebih besar dari yang awal, DAN ada ruang disk yang cukup), dan ekspansi semacam itu meningkatkan batas komit yang cukup untuk membuat panggilan VirtualAlloc berhasil, lalu ... Mm memperluas pagefile, dan panggilan VirtualAlloc berhasil.
Dan saat itulah Anda melihat "sistem menjalankan RENDAH pada memori". Itu adalah peringatan dini bahwa jika hal-hal berlanjut tanpa mitigasi Anda kemungkinan akan segera melihat peringatan "kehabisan memori". Saatnya menutup beberapa aplikasi. Saya akan mulai dengan windows browser Anda.
Dan Anda pikir itu hal yang baik? Ekspansi Pagefile itu jahat !!!
Tidak. Lihat, OS tidak benar-benar "memperluas" file yang ada. Itu hanya mengalokasikan tingkat baru. Efeknya sangat mirip dengan file non-berdekatan lainnya. Konten pagefile lama tetap di tempatnya; mereka tidak harus disalin ke tempat baru atau semacamnya. Karena sebagian besar IO pagefile dalam potongan yang relatif kecil dibandingkan dengan ukuran pagefile, kemungkinan bahwa setiap transfer yang diberikan akan melewati batas batas yang sangat jarang, sehingga fragmentasi tidak banyak sakit kecuali itu benar-benar berlebihan.
Akhirnya, setelah semua proses yang memiliki "komitmen" ruang dalam ekstensi telah berhenti (pada penutupan OS jika tidak lebih cepat), luasan dibebaskan secara diam-diam dan pagefile akan kembali ke ukuran dan alokasi sebelumnya - jika berdekatan sebelumnya, itu begitu lagi.
Sehingga memungkinkan ekspansi pagefile bertindak sebagai jaring pengaman benar-benar gratis: Jika Anda membiarkan hal itu tetapi sistem tidak pernah membutuhkannya, sistem akan tidak "terus-menerus memperluas dan kontrak pagefile" seperti yang sering diklaim, sehingga akan dikenakan biaya apa-apa . Dan jika Anda memang membutuhkannya, itu akan menyelamatkan Anda dari aplikasi yang mengalami kesalahan "kehabisan memori virtual".
Tapi tapi ...
Saya telah membaca di puluhan situs web bahwa jika Anda mengizinkan ekspansi pagefile Windows akan terus-menerus memperluas dan mengontrak pagefile, dan ini akan mengakibatkan fragmentasi pagefile hingga Anda mendefrag.
Mereka salah.
Jika Anda belum pernah melihat "kehabisan memori" (atau, dalam versi yang lebih lama, "kehabisan memori virtual") pop-up, OS tidak pernah memperluas pagefile Anda.
Jika Anda melihat pop-up itu, maka itu memberitahu Anda ukuran pagefile awal Anda terlalu kecil. (Saya suka mengaturnya menjadi sekitar 4x penggunaan maksimum yang diamati; yaitu penghitung perfmon "% pagefile use peak" harus di bawah 25%. Alasan: Ruang Pagefile dikelola seperti tumpukan lainnya dan berfungsi dengan baik dengan banyak ruang kosong untuk bermain.)
Tapi kenapa mereka tidak ...
Orang mungkin berpendapat bahwa OS seharusnya membiarkan alokasi terjadi dan kemudian membiarkan referensi gagal jika tidak ada RAM yang tersedia untuk menyelesaikan kesalahan halaman. Dengan kata lain, di atas di mana kami menggambarkan bagaimana kesalahan halaman awal bekerja, bagaimana jika "mengalokasikan halaman fisik RAM yang tersedia" (langkah 1) tidak dapat dilakukan karena tidak ada yang tersedia, dan tidak ada tempat dibiarkan halaman apa saja untuk membuat tersedia?
Maka pager tidak akan bisa menyelesaikan kesalahan halaman. Harus memungkinkan pengecualian (kesalahan halaman) dilaporkan kembali ke utas yang rusak, mungkin diubah ke beberapa kode pengecualian lainnya.
Filosofi desainnya adalah bahwa VirtualAlloc akan mengembalikan nol (secara teknis penunjuk NULL) alih-alih alamat jika Anda kehabisan batas komit, dan sepenuhnya masuk akal untuk mengharapkan programmer mengetahui bahwa panggilan VirtualAlloc dapat gagal. Jadi programmer diharapkan untuk memeriksa kasus itu dan melakukan sesuatu yang masuk akal sebagai tanggapan (seperti memberi Anda kesempatan untuk menyelamatkan pekerjaan Anda sampai titik itu, dan kemudian mengakhiri program "dengan anggun"). (Programmer: Anda memeriksa pengembalian pointer NULL dari malloc, baru, dll, ya? Lalu mengapa Anda tidak melakukan ini?)
Tetapi programmer tidak harus mengharapkan referensi memori yang sederhana seperti itu
mungkin gagal - tidak jika berada di wilayah ruang alamat yang berhasil dilakukan. (Atau ruang alamat yang dipetakan, dalam hal ini.) Tetapi itulah yang bisa terjadi jika filosofi "izinkan alokasi berlebihan, biarkan referensi memori gagal" diikuti.
Sayangnya, referensi memori seperti yang ada di baris kode di atas tidak memiliki cara yang nyaman untuk mengembalikan status buruk! Mereka seharusnya bekerja , seperti penambahan dan pengurangan. Satu-satunya cara untuk melaporkan kegagalan tersebut adalah sebagai pengecualian. Jadi untuk menangani mereka, programmer harus membungkus seluruh program dalam sebuah handler pengecualian. (coba ... tangkap dan semua itu.)
Itu bisa dilakukan ... Tetapi akan sulit bagi pawang untuk mengetahui bagaimana "melakukan hal yang benar" sebagai tanggapan terhadap pengecualian itu, karena akan ada begitu banyak, banyak poin dalam kode di mana mereka dapat muncul. (Secara khusus, mereka dapat muncul di setiap referensi memori ke memori VirtualAlloc'd, ke memori yang dialokasikan dengan malloc atau baru ... dan ke semua variabel lokal juga, karena tumpukan juga VirtualAlloc.)
Singkatnya, membuat program gagal dengan anggun dalam kasus-kasus ini akan sangat sulit.
Sangat mudah, di sisi lain, untuk memeriksa pengembalian pointer NULL dari VirtualAlloc (atau malloc atau baru, dalam hal ini, meskipun mereka tidak persis hal yang sama) dan kemudian melakukan sesuatu yang masuk akal ... seperti tidak mencoba untuk pergi dan lakukan apa pun program itu membutuhkan ruang virtual untuk. Dan mungkin bertanya kepada pengguna apakah mereka ingin menyimpan pekerjaan mereka sejauh ini, jika ada. (Memang, terlalu banyak aplikasi yang tidak repot melakukan hal sebanyak itu.)
Pengguna komit lainnya
Secara kebetulan, "batas komit" tidak dikurangi oleh berbagai alokasi OS seperti kumpulan halaman dan non-halaman, daftar PFN, dll .; ini hanya dibebankan untuk melakukan biaya saat terjadi. Juga tidak ada biaya komit atau batas komit yang dipengaruhi oleh RAM video, atau bahkan ukuran "jendela" RAM video.
Uji sendiri
Anda dapat memperagakan semua ini dengan alat testlimit dari situs SysInternals. Opsi -m akan mengalokasikan ruang alamat yang dikomit tetapi tidak akan "menyentuhnya", jadi tidak akan menyebabkan alokasi RAM. Sedangkan opsi -d akan mengalokasikan dan juga mereferensikan halaman, menyebabkan biaya komit meningkat dan RAM yang tersedia berkurang.
Referensi
Windows Internal oleh Russinovich, Solomon, dan Ionescu. Bahkan ada demonstrasi yang memungkinkan Anda untuk membuktikan semua poin ini menggunakan alat testlimit. Namun, saya harus memperingatkan Anda bahwa jika Anda pikir ini panjang, berhati-hatilah: bab Mm saja 200 halaman; yang di atas adalah versi yang sangat disederhanakan. (Harap juga melirik bagian "Ucapan Terima Kasih" di Pendahuluan.)
Lihat juga dokumentasi MSDN VirtualAlloc
sumber