Apakah memori "Cached" benar-benar gratis?

11

Saat berjalan cat /proc/meminfo, Anda mendapatkan 3 nilai ini di atas:

MemTotal:        6291456 kB
MemFree:         4038976 kB
Cached:          1477948 kB

Sejauh yang saya tahu, nilai "Cached" adalah cache disk yang dibuat oleh sistem Linux yang akan segera dibebaskan jika ada aplikasi yang membutuhkan lebih banyak RAM, sehingga Linux tidak akan pernah kehabisan memori sampai kedua MemFree dan Cached berada di nol.

Sayangnya, "MemAvailable" tidak dilaporkan oleh / proc / meminfo, mungkin karena sedang berjalan di server virtual. (Versi kernel adalah 4.4)

Jadi untuk semua tujuan praktis, RAM yang tersedia untuk aplikasi adalah MemFree + Cached.

Apakah pandangan itu benar?

Roland Seuhs
sumber
1
Saya tidak ingin palu emas ini ditutup, tetapi pertanyaan ini relevan jika bukan duplikat. Saya terkejut Anda tidak memilikinya MemAvailable, ditambahkan pada 3.14.
Stephen Kitt
Jawaban yang diterima dari pertanyaan itu menggunakan / proc / zoneinfo, yang juga tidak tersedia di vserver saya
Roland Seuhs
uname -a: Tuan rumah Linux 4.4.0-042stab134.8 # 1 SMP Jumat 7 Des 17:16:09 MSK 2018 x86_64 x86_64 x86_64 GNU / Linux
Roland Seuhs
Saya menduga ini adalah sistem OpenVZ dengan kernel yang benar-benar didasarkan pada 2.6.32, bukan 4.4.
Stephen Kitt
1
@sourcejedi dan dikompilasi pada waktu yang sama persis dengan kernel 4.4!
Stephen Kitt

Jawaban:

10

Pandangan itu bisa sangat menyesatkan dalam sejumlah kasus di dunia nyata.

Kernel sekarang menyediakan perkiraan untuk memori yang tersedia, di MemAvailablelapangan. Nilai ini berbeda secara signifikan dari MemFree + Cached.

/ proc / meminfo: berikan perkiraan memori yang tersedia [deskripsi perubahan kernel, 2014]

Banyak program load balancing dan beban kerja memeriksa / proc / meminfo untuk memperkirakan berapa banyak memori bebas yang tersedia. Mereka umumnya melakukan ini dengan menambahkan "gratis" dan "cache", yang baik-baik saja sepuluh tahun yang lalu, tetapi cukup banyak dijamin salah hari ini.

Itu salah karena Cached memasukkan memori yang tidak bebas sebagai cache halaman, misalnya segmen memori bersama, tmpfs, dan ramfs, dan itu tidak termasuk memori slab yang dapat direklamasi, yang dapat mengambil sebagian besar memori sistem pada kebanyakan sistem idle dengan banyak file.

Saat ini, jumlah memori yang tersedia untuk beban kerja baru, tanpa mendorong sistem ke swap, dapat diperkirakan dari MemFree, Active (file), Inactive (file), dan SReclaimable, serta tanda air "rendah" dari / proc / zoneinfo. Namun, ini mungkin berubah di masa depan, dan ruang pengguna benar-benar tidak boleh diharapkan untuk mengetahui kernel internal untuk menghasilkan perkiraan jumlah memori bebas. Lebih mudah menyediakan perkiraan seperti itu di / proc / meminfo. Jika ada perubahan di masa depan, kita hanya perlu mengubahnya di satu tempat.
...

Dokumentasi / sistem file / proc.txt:
...
MemAvailable: Perkiraan berapa banyak memori yang tersedia untuk memulai aplikasi baru, tanpa bertukar. Dihitung dari MemFree, SReclaimable, ukuran daftar file LRU, dan tanda air rendah di setiap zona. Perkiraan memperhitungkan bahwa sistem membutuhkan beberapa cache halaman agar berfungsi dengan baik, dan bahwa tidak semua pelat yang dapat direklamasi akan dapat direklamasi, karena item-item sedang digunakan. Dampak dari faktor-faktor tersebut akan bervariasi dari satu sistem ke sistem lainnya.

1. Rincian MemAvailable

Seperti dikatakan di atas, tmpfs dan Shmemmemori lain tidak dapat dibebaskan, hanya dipindahkan ke swap. Cacheddi /proc/meminfobisa sangat menyesatkan, karena termasuk Shmemmemori swappable ini . Jika Anda memiliki terlalu banyak file dalam tmpfs, itu bisa menempati banyak memori Anda :-). Shmemjuga dapat menyertakan beberapa alokasi memori grafis , yang bisa sangat besar.

MemAvailablesengaja tidak termasuk memori swappable. Bertukar terlalu banyak dapat menyebabkan penundaan lama. Anda bahkan mungkin memilih untuk berjalan tanpa ruang swap, atau hanya diizinkan dalam jumlah yang relatif terbatas.

Saya harus memeriksa ulang cara MemAvailablekerjanya. Sepintas, kode itu sepertinya tidak menyebutkan perbedaan ini.

/*
 * Not all the page cache can be freed, otherwise the system will
 * start swapping. Assume at least half of the page cache, or the
 * low watermark worth of cache, needs to stay.
 */
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);
available += pagecache;

Namun, saya menemukan itu benar memperlakukan Shmemsebagai memori "bekas". Saya membuat beberapa file 1GB dalam tmpfs. Setiap peningkatan 1GB Shmemdikurangi MemAvailable1GB. Jadi ukuran "daftar file LRU" tidak termasuk memori bersama atau memori swappable lainnya. (Saya perhatikan jumlah halaman yang sama juga digunakan dalam kode yang menghitung "batas kotor" ).

MemAvailablePerhitungan ini juga mengasumsikan bahwa Anda ingin menyimpan cache file setidaknya cukup untuk sama dengan "tanda air rendah" kernel. Atau setengah dari cache saat ini - mana yang lebih kecil. (Itu membuat asumsi yang sama untuk lempengan yang dapat direklamasi juga). Kernel "low watermark" dapat disetel, tetapi biasanya sekitar 2% dari RAM sistem . Jadi, jika Anda hanya menginginkan perkiraan kasar, Anda dapat mengabaikan bagian ini :-).

Ketika Anda menjalankan firefoxdengan sekitar 100MB kode program yang dipetakan dalam halaman cache, Anda biasanya ingin menyimpan 100MB itu dalam RAM :-). Kalau tidak, paling baik Anda akan mengalami penundaan, paling buruk sistem akan menghabiskan semua waktu meronta - ronta antara aplikasi yang berbeda. Jadi MemAvailablememungkinkan persentase kecil RAM untuk ini. Itu mungkin tidak cukup memungkinkan, atau mungkin terlalu murah hati. "Dampak dari faktor-faktor itu akan bervariasi dari satu sistem ke sistem".

Untuk banyak beban kerja PC, poin tentang "banyak file" mungkin tidak relevan. Meski begitu, saat ini saya memiliki memori slab 500MB yang dapat direklamasi di laptop saya (dari 8GB RAM). Ini disebabkan oleh ext4_inode_cache(lebih dari 300 ribu objek). Itu terjadi karena saya baru-baru ini harus memindai seluruh sistem file, untuk menemukan apa yang menggunakan ruang disk saya :-). Saya menggunakan perintah df -x / | sort -n, tetapi misalnya Gnome Disk Usage Analyzer akan melakukan hal yang sama.

2. [Sunting] Memori dalam kelompok kontrol

Jadi yang disebut "Linux wadah" yang dibangun dari namespaces, cgroups, dan berbagai fitur lainnya sesuai selera :-). Mereka mungkin menyediakan lingkungan yang cukup meyakinkan untuk menjalankan sesuatu yang hampir seperti sistem Linux penuh. Layanan hosting dapat membuat wadah seperti ini dan menjualnya sebagai "server virtual" :-).

Server hosting juga dapat membangun "server virtual" menggunakan fitur-fitur yang tidak ada dalam Linux arus utama. OpenVZ memuat pra-tanggal cgroup jalur utama selambat-lambatnya dua tahun, dan dapat menggunakan "beancounters" untuk membatasi memori. Jadi, Anda tidak dapat memahami dengan tepat bagaimana batas memori tersebut berfungsi jika Anda hanya membaca dokumen atau mengajukan pertanyaan tentang kernel Linux mainline. cat /proc/user_beancountersmenunjukkan penggunaan dan batasan saat ini. vzubcmenyajikannya dalam format yang sedikit lebih ramah. The halaman utama pada beancounters mendokumentasikan nama baris.

Grup kontrol mencakup kemampuan untuk menetapkan batas memori pada proses di dalamnya. Jika Anda menjalankan aplikasi di dalam cgroup seperti itu, maka tidak semua memori sistem akan tersedia untuk aplikasi :-). Jadi, bagaimana kita bisa melihat memori yang tersedia dalam kasus ini?

Antarmuka untuk ini berbeda dalam beberapa cara, tergantung jika Anda menggunakan cgroup-v1 atau cgroup-v2 .

Instalasi laptop saya menggunakan cgroup-v1. Saya bisa lari cat /sys/fs/cgroup/memory/memory.stat. File menunjukkan berbagai bidang termasuk total_rss, total_cache, total_shmem. shmem, termasuk tmpfs, diperhitungkan dalam batas memori. Saya kira Anda dapat melihat total_rsssebagai setara terbalik MemFree. Dan ada juga file memory.kmem.usage_in_bytes, yang mewakili memori kernel termasuk lempengan. (Saya berasumsi memory.kmem.juga termasuk memory.kmem.tcp.dan ekstensi di masa depan, meskipun ini tidak didokumentasikan secara eksplisit). Tidak ada penghitung terpisah untuk melihat memori pelat yang dapat direklamasi. Dokumen untuk cgroup-v1 mengatakan bahwa memukul batas memori tidak memicu pengambilan kembali memori slab apa pun. (Dokumen ini juga memiliki penafian bahwa dokumen itu "sudah usang", dan Anda harus memeriksa kode sumber saat ini).

cgroup-v2 berbeda. Saya pikir cgroup root (tingkat atas) tidak mendukung akuntansi memori. cgroup-v2 masih memiliki memory.statfile. Semua bidang berjumlah lebih dari cgroup anak, jadi Anda tidak perlu mencari total_...bidang. Ada filebidang, yang berarti hal yang sama cachelakukan. Mengganggu saya tidak melihat bidang keseluruhan seperti rssdi dalam memory.stat; Saya kira Anda harus menambahkan bidang individual. Ada statistik terpisah untuk memori slab yang dapat direklamasi dan tidak dapat diklaim kembali; Saya pikir cgroup v2 dirancang untuk mendapatkan kembali slab ketika mulai kehabisan memori.

Linux cgroups tidak secara otomatis melakukan virtualisasi /proc/meminfo(atau file lain apa pun /proc), sehingga akan menunjukkan nilai untuk seluruh mesin. Ini akan membingungkan pelanggan VPS. Namun dimungkinkan untuk menggunakan ruang nama untuk menggantikan /proc/meminfodengan file yang dipalsukan oleh perangkat lunak wadah tertentu . Seberapa berguna nilai-nilai palsu itu, akan tergantung pada apa yang dilakukan perangkat lunak tertentu.

systemdpercaya cgroup-v1 tidak dapat dengan aman didelegasikan misalnya ke wadah. Saya melihat ke dalam sebuah systemd-nspawnwadah di sistem cgroup-v1 saya. Saya dapat melihat cgroup yang telah ditempatkan di dalamnya, dan ingatannya mengenai itu. Di sisi lain, isi systemdtidak mengatur kelompok per layanan yang biasa untuk akuntansi sumber daya. Jika penghitungan memori tidak diaktifkan di dalam cgroup ini, saya berasumsi kontainer tidak akan dapat mengaktifkannya.

Saya berasumsi jika Anda berada di dalam wadah cgroup-v2, itu akan terlihat berbeda dengan akar sistem cgroup-v2 nyata, dan Anda akan dapat melihat memori akuntansi untuk cgroup tingkat atas. Atau jika cgroup yang Anda lihat tidak memiliki penghitungan memori yang diaktifkan, mudah-mudahan Anda akan didelegasikan izin sehingga Anda dapat mengaktifkan penghitungan memori dalamsystemd (atau yang setara).

sourcejedi
sumber
1
itu clicky nao. Saya menggunakan tautan GitHub karena menunjukkan rilis pertama yang mengandung komit (mirip dengan git describe --contains). Menemukannya ditautkan sebagai TL; DR oleh pertanyaan SU, yang ternyata hanya mengutip bagian yang ditambahkan ke proc.txt. Tetapi untuk pertanyaan ini, deskripsi commit adalah IMO yang sempurna :-).
sourcejedi
MemAvailable tampaknya tidak tersedia di sebagian besar server virtual ... lalu apa yang harus dilakukan?
Roland Seuhs
@RolandSeuhs mungkin belajar "beancounters". Lihat hasil edit dalam huruf tebal. Jika Anda memiliki pertanyaan tentang beancounters, saya akan sangat menghargai jika Anda mengajukan pertanyaan baru. Kami selalu dapat menautkannya dari yang ini, tetapi detailnya mungkin tidak relevan bagi pembaca yang menggunakan kernel linux mainline.
sourcejedi