Apakah ada cara untuk mendeteksi fragmentasi memori di linux? Ini karena pada beberapa server yang berjalan lama saya telah melihat penurunan kinerja dan hanya setelah saya me-restart proses saya melihat kinerja yang lebih baik. Saya lebih memperhatikan ketika menggunakan dukungan halaman besar linux - apakah halaman besar di linux lebih rentan terhadap fragmentasi?
Saya telah melihat / proc / buddyinfo secara khusus. Saya ingin tahu apakah ada cara yang lebih baik (bukan hanya perintah CLI per se, program atau latar belakang teoritis yang akan dilakukan) untuk melihatnya.
linux
linux-kernel
Raghu
sumber
sumber
vmstat
di lapanganso
?vmstat
adalah pengalaman pengguna yang umum. Jika Anda menulis program untuk melakukan hal yang sama, itu akan berbeda. Jika Anda berniat menggunakan bash untuk memanen info ini, edit pertanyaan Anda, itu tidak akan ditutup :)Jawaban:
Saya menjawab tag linux . Jawaban saya hanya khusus untuk Linux .
Ya, halaman besar lebih rentan terhadap fragmentasi. Ada dua tampilan memori, yang proses Anda (virtual) dan yang dikelola kernel (nyata). Semakin besar halaman apa pun, semakin sulit untuk mengelompokkan (dan menyimpannya) dengan tetangganya, terutama ketika layanan Anda berjalan pada sistem yang juga harus mendukung orang lain yang secara default mengalokasikan dan menulis ke memori yang jauh lebih banyak daripada mereka. sebenarnya berakhir menggunakan.
Pemetaan kernel dari alamat (nyata) yang diberikan bersifat pribadi. Ada alasan yang sangat bagus mengapa userspace melihatnya sebagai kernel yang mempresentasikannya, karena kernel harus dapat overcommit tanpa membingungkan userspace. Proses Anda mendapatkan ruang alamat "Disneyfied" yang bagus dan berdekatan tempat untuk bekerja, tanpa mengetahui apa yang sebenarnya dilakukan kernel dengan memori di belakang layar.
Alasan Anda melihat kinerja yang menurun pada server yang berjalan lama kemungkinan besar karena blok yang dialokasikan yang belum dikunci secara eksplisit (misalnya
mlock()
/mlockall()
atauposix_madvise()
) dan tidak dimodifikasi dalam beberapa saat telah dikeluarkan , yang berarti layanan Anda tergelincir ke disk ketika harus membaca mereka. Mengubah perilaku ini membuat proses Anda menjadi tetangga yang buruk , itulah sebabnya banyak orang meletakkan RDBMS mereka di server yang sama sekali berbeda dari web / php / python / ruby / apa pun. Satu-satunya cara untuk memperbaikinya, secara waras, adalah mengurangi persaingan untuk blok yang berdekatan.Fragmentasi hanya benar-benar terlihat (dalam kebanyakan kasus) ketika halaman A ada dalam memori dan halaman B telah pindah untuk bertukar. Secara alami, memulai kembali layanan Anda tampaknya akan 'menyembuhkan' ini, tetapi hanya karena kernel belum memiliki kesempatan untuk membatalkan proses '(sekarang) blok-blok yang baru dialokasikan dalam batas rasio overcommit-nya.
Bahkan, memulai kembali (katakanlah) 'apache' di bawah beban tinggi kemungkinan akan mengirim blok yang dimiliki oleh layanan lain langsung ke disk. Jadi ya, 'apache' akan meningkat untuk waktu yang singkat, tetapi 'mysql' mungkin menderita .. setidaknya sampai kernel membuat mereka menderita secara sama ketika hanya ada kekurangan memori fisik yang cukup.
Tambahkan lebih banyak memori, atau pisahkan
malloc()
konsumen yang menuntut :) Bukan hanya fragmentasi yang perlu Anda perhatikan.Cobalah
vmstat
untuk mendapatkan gambaran umum tentang apa yang sebenarnya disimpan di mana.sumber
Inti
Untuk mendapatkan indeks fragmentasi saat ini, gunakan:
Untuk mendefrag memori kernel coba jalankan:
Anda juga mencoba mematikan Halaman Besar Transparan (alias THP) dan / atau menonaktifkan swap (atau mengurangi
swappiness
).Ruang pengguna
Untuk mengurangi fragmentasi userspace Anda mungkin ingin mencoba pengalokasi yang berbeda, misalnya
jemalloc
(ia memiliki kemampuan introspeksi yang hebat , yang akan memberi Anda bagian dalam ke dalam fragmentasi internal pengalokasi).Anda dapat beralih ke malloc kustom dengan mengkompilasi ulang program Anda dengannya atau hanya dengan menjalankan program Anda dengan
LD_PRELOAD
:LD_PRELOAD=${JEMALLOC_PATH}/lib/libjemalloc.so.1 app
(waspadalah terhadap interaksi antara THP dan pengalokasi memori memori )Meskipun, sedikit tidak terkait dengan fragmentasi memori (tetapi terhubung ke pemadatan / migrasi memori), Anda mungkin ingin menjalankan beberapa instance layanan Anda, satu untuk setiap NUMA node dan mengikatnya menggunakan
numactl
.sumber
mmap
) yang dilaksanakan berbeda pada kernel yang berbeda (misalnya Linux vs FreeBSD), atau bahkan versi yang berbeda dari OS yang sama (2.6.32 vs 3,2 vs 3,10) .. "itu izin-izin halaman dimodifikasi [. ..] akan dikeluarkan dari [...] memori fisik "- yang akan menyembunyikan kebocoran memori. "menangani kasus-kasus di mana lebih banyak memori dicadangkan daripada digunakan" - sistem lambat jauh lebih buruk daripada sistem turun, jadi "waras" dipertanyakan.Menggunakan halaman besar seharusnya tidak menyebabkan fragmentasi memori ekstra di Linux; Dukungan Linux untuk halaman besar hanya untuk memori bersama (via shmget atau mmap), dan setiap halaman besar yang digunakan harus secara khusus diminta dan dialokasikan sebelumnya oleh admin sistem. Setelah di memori, mereka disematkan di sana, dan tidak ditukar. Tantangan untuk menukar halaman-halaman besar dalam menghadapi fragmentasi memori adalah persis mengapa mereka tetap tersemat dalam memori (ketika mengalokasikan halaman besar 2MB, kernel harus menemukan 512 halaman 4KB gratis yang berdekatan, yang bahkan mungkin tidak ada).
Dokumentasi Linux pada halaman besar: http://lwn.net/Articles/375098/
Ada satu keadaan di mana fragmentasi memori dapat menyebabkan alokasi halaman besar menjadi lambat (tetapi tidak di mana halaman besar menyebabkan fragmentasi memori), dan itulah jika sistem Anda dikonfigurasi untuk menumbuhkan kumpulan halaman besar jika diminta oleh aplikasi. Jika / proc / sys / vm / nr_overcommit_hugepages lebih besar dari / proc / sys / vm / nr_hugepages, ini mungkin terjadi.
sumber
Ada
/proc/buddyinfo
yang sangat bermanfaat. Ini lebih berguna dengan format output yang bagus, seperti yang dapat dilakukan skrip Python ini:https://gist.github.com/labeneator/9574294
Untuk halaman besar Anda ingin beberapa fragmen gratis dalam ukuran 2097152 (2MiB) atau lebih besar. Untuk halaman besar transparan, ia akan memadat secara otomatis ketika kernel diminta untuk beberapa, tetapi jika Anda ingin melihat berapa banyak yang bisa Anda dapatkan, maka sebagai root run:
Juga ya, halaman besar menyebabkan masalah besar bagi fragmentasi. Entah Anda tidak bisa mendapatkan halaman besar, atau kehadirannya menyebabkan kernel menghabiskan banyak waktu ekstra untuk mencoba mendapatkan sebagian.
Saya punya solusi yang berfungsi untuk saya. Saya menggunakannya di beberapa server dan laptop saya. Ini bekerja bagus untuk mesin virtual.
Tambahkan
kernelcore=4G
opsi ke baris perintah kernel Linux Anda. Di server saya, saya menggunakan 8G. Berhati-hatilah dengan nomor tersebut, karena itu akan mencegah kernel Anda mengalokasikan apa pun di luar memori itu. Server yang membutuhkan banyak soket buffer atau disk streaming yang menulis ke ratusan drive tidak akan suka dibatasi seperti ini. Setiap alokasi memori yang harus "disematkan" untuk slab atau DMA ada dalam kategori ini.Semua memori Anda yang lain kemudian menjadi "bergerak" yang artinya dapat dipadatkan menjadi potongan-potongan bagus untuk alokasi halaman yang besar. Sekarang halaman besar transparan benar-benar dapat lepas landas dan berfungsi sebagaimana mestinya. Setiap kali kernel membutuhkan lebih banyak halaman 2M, ia hanya dapat memetakan kembali halaman 4K ke tempat lain.
Dan, saya tidak sepenuhnya yakin bagaimana ini berinteraksi dengan IO langsung zero-copy. Memori di "zona bergerak" tidak seharusnya disematkan, tetapi permintaan IO langsung akan melakukan hal itu untuk DMA. Mungkin menyalinnya. Lagipula itu mungkin menyematkannya di zona bergerak. Dalam kedua kasus itu mungkin bukan yang Anda inginkan.
sumber