Bu eski bir yazı, ancak yine de düşüncelerimi buraya koyma özgürlüğünü alırdım.
Aşağıdan başlayarak, Linux ilk önce belleği sayfalara böler (genellikle x86_64 sisteminde sayfa başına 4K). Bundan sonra, eşlemesi MMU (Bellek Yönetim Birimi) kullanılarak fiziksel bellekle yapılan sanal bellek yaratılır.
İşlemler sanal bellek alanından bellek tahsis edilir, bu nedenle lütfen unutmayın, / proc / meminfo dosyasını gördüğünüzde sanal bellek detayları olarak VMalloc * 'u göreceksiniz.
Diyelim ki bellek isteyen bir işleminiz var (diyelim 300 MB - bir web tarayıcısı). İşlem sanal bellekten 300 MB tahsis edilecektir, ancak eşleştirilmesi gerekmemektedir (fiziksel belleğe eşlenmiştir). Bellek yönetimi için "Yazma Kopyalama" kavramı vardır, bu sayede işlemleriniz gerçekten sanal bellekten tahsis edilen belleği kullanırsa (yani belleğe bir miktar yazma işlemi yapar), ancak o zaman fiziksel belleğe eşlenir. Bu, çekirdeğin çok işlemeli bir ortamda verimli şekilde çalışmasına yardımcı olur.
Önbellek nedir?
İşlemler tarafından kullanılan çok fazla bellek paylaşılıyor. Diyelim ki glibc kütüphanesi hemen hemen bütün işlemler tarafından kullanılıyor. Her işlem aynı bellek konumuna erişip işi yapabildiği zaman, birden fazla glibc kopyasını bellekte tutmanın amacı nedir. Bu sık kullanılan kaynaklar önbellekte tutulur, böylece işlemler talep edildiğinde aynı bellek konumuna yönlendirilebilirler. Bu, glibc'nin (vb.) Tekrar tekrar diskten okunması zaman alacağından işlemleri hızlandırmaya yardımcı olur.
Yukarıda belirtilenler, paylaşılan kütüphaneler için geçerliydi, benzer aynı zamanda dosya okuması için de geçerlidir. Büyük bir dosyayı ilk defa okuyorsanız (100-200 MB deyince) çok zaman alacaktı. Ancak, aynı okumayı tekrar denediğinizde, daha hızlı olur. Veriler bellekte önbelleğe alındı ve tüm bloklar için yeniden okuma yapılmadı.
Tampon nedir?
Tampon söz konusu olduğunda, bir işlem dosya G / Ç yaptığında, diske veri yazmak için çekirdeğin arabelleğine güvenir. İşlemler, çekirdeğin işi yapmasını ister. Böylece, işlem adına, çekirdek, verileri "arabelleğine" yazar ve işleme yazmanın yapıldığını söyler. Eşzamansız bir şekilde, çekirdek bu verileri arabellekte diske eşitlemeye devam edecektir. Bu şekilde, süreçler diske veri senkronize etmek için doğru zamanı seçmek için çekirdeğe dayanmaktadır ve işlemler ileride çalışmaya devam edebilir. Unutmayın, bu normal işlemlerin yaptığı genel G / Ç'dir. Ancak, G / Ç'nin aslında disk üzerinde yapıldığını onaylaması gereken özel işlemler, diskte G / Ç yapmak için başka mekanizmalar kullanabilir. Açık kaynak kodlu araçlardan bazıları libaio'dur. Ayrıca, işlemler bağlamınızda açılan FD'lere açık senkronizasyon çağırmanın yolları vardır,
O zaman sayfa hataları nelerdir?
İkili yaklaşık 300 MB olan bir işlemi başlattığınızda (bir web tarayıcısı deyin) bir örnek düşünün. Bununla birlikte, 300 MB’lık web tarayıcısının ikilisi anında çalışmaya başlamaz. İşlem kodunda fonksiyonlardan fonksiyonlara geçmeye devam ediyor. Daha önce de belirtildiği gibi, Sanal Bellek 300 MB tüketilecek, ancak tümü fiziksel belleğe eşlenen bellek değildir (RSS yerleşik belleği daha az olacaktır, en üst çıktısına bakınız). Kod yürütme, belleğin fiziksel olarak eşlenmemiş olduğu bir noktaya ulaştığında, bir sayfa hatası ortaya çıkar. Çekirdek bu belleği fiziksel olarak eşleştirir, bellek sayfasını işleminizle ilişkilendirir. Böyle bir sayfa hatasına "Küçük Sayfa Hataları" denir. Benzer şekilde, bir işlem dosya yaparken, G / Ç ana sayfa hataları ortaya çıkar.
Swap Out ne zaman ve neden oluyor?
Durum 1:
Yukarıdaki ayrıntılarla aynı çizgide, iyi miktarda bellek eşlendiğinde, bir senaryoyu düşünelim. Ve şimdi hafıza gerektiren bir süreç başlıyor. Yukarıda tartışıldığı gibi, çekirdek bazı bellek haritalaması yapacaktır. Ancak, belleği eşleştirmek için yeterli fiziksel RAM yok. Şimdi, çekirdek önce önbelleğe bakacak, kullanılmayan bazı eski bellek sayfalarına sahip olacak. Bu sayfaları ayrı bir bölüme (SWAP adı verilir) temizler, bazı sayfaları boşaltır ve serbest bırakılan sayfaları gelen yeni istekle eşleştirir. Diske yazma katı hal RAM'inden çok daha yavaş olduğundan, bu işlem çok zaman alır ve bu nedenle yavaşlama görülür.
Durum 2:
Diyelim ki sistemde bir sürü boş hafıza olduğunu görelim. O zaman bile, bir sürü takas yaşandığını görüyorsunuz. Muhtemel bir hafıza parçalanması sorunu olabilir. Çekirdekten 50 MB'lık bitişik bellek gerektiren bir işlem düşünün. (akılda tutulması akılda tutulması). Açıkçası, çekirdek rasgele sayfaları farklı işlemlere ayırmış ve bazılarını serbest bırakmış olurdu. Bununla birlikte, sürekli bellek talep ettiğimizde, süreç talebini karşılayan bir yığın aramak zorunda kalacaktır. Eğer böyle bir hafızaya sahip olamıyorsa, bazı eski hafıza sayfalarını değiştirmek ve ardından bitişik olanları tahsis etmek zorunda kalacaktır. Bu gibi durumlarda bile SWAP çıkışı olur. 2.6 ve üzeri sürümlerde başlayan Kernel, bu tür parçalanma problemlerini önemli ölçüde azaltmıştır. Bununla birlikte, sistem uzun bir süredir çalışıyorsa, bu tür sorunlar yine de ortaya çıkabilir.
Bu örneğe bakın ( vmstat çıkışı )
2016-10-29 03:55:32 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
2016-10-29 03:55:32 r b swpd free buff cache si so bi bo in cs us sy id wa st
2016-10-30 03:56:04 19 23 2914752 4692144 3344908 12162628 1660 1 8803 12701 4336 37487 14 7 40 38 0
2016-10-30 03:56:34 3 20 2889296 4977580 3345316 12026752 2109 2 8445 14665 4656 36294 12 7 46 34 0
2016-10-30 03:57:04 1 11 3418868 4939716 3347804 11536356 586 4744 2547 9535 3086 24450 6 3 59 33 0 <<<-----
2016-10-30 03:57:34 3 19 3456252 5449884 3348400 11489728 3291 13371 6407 17957 2997 22556 6 4 66 24 0
2016-10-30 03:58:04 7 6 4194500 5663580 3349552 10857424 2407 12240 3824 14560 2295 18237 4 2 65 29 0
2016-10-30 03:58:34 2 16 4203036 5986864 3348908 10838492 4601 16639 7219 18808 2575 21563 6 4 60 31 0
2016-10-30 03:59:04 3 14 4205652 6059196 3348760 10821448 6624 1597 9431 4357 1750 20471 6 2 60 31 0
2016-10-30 03:59:34 2 24 4206968 6053160 3348876 10777216 5221 2067 10106 7377 1731 19161 3 3 62 32 0
2016-10-30 04:00:04 0 13 4205172 6005084 3348932 10785896 6236 1609 10330 6264 1739 20348 4 2 67 26 0
2016-10-30 04:00:34 4 11 4206420 5996396 3348976 10770220 6554 1253 10382 4896 1964 42981 10 5 58 27 0
2016-10-30 04:01:04 6 4 4177176 5878852 3348988 10825840 8682 765 10126 2716 1731 32949 8 4 69 19 0
@ 2016-10-30 03:57:04, hala iyi miktarda boş RAM olduğunu görüyoruz. Ancak, o zaman bile takas oldu. İşlem ağacını bu noktada kontrol ettik ve bu kadar yüksek miktarda bellek (boş bellekten daha fazlası) gerektiren herhangi bir işlemin geldiğini görmedik. Açıkça şüphe, yukarıda açıklanan Durum 2 idi. Yukarıdaki buddyinfo ve zoneinfo loglarını kontrol ettik (bunları kontrol etmek için echo m> / proc / sysrq-trigger kullanın, çıkış syslog'lara gider).
Bizim normal bir sistemimiz için, bölge bilgisinin karşılaştırılması buna gider. Ve önbellek / ücretsiz / düşük mem grafikleri aşağıda da belirtilmiştir
Bilgiye bakıldığında, normal düğüm 0 ve düğüm 1'de bellek parçalanması olduğu açıktır (düğüm NUMA tabanlı bir makinedir, bu nedenle çoklu düğümler (sisteminiz için bilgileri kontrol etmek için numactl'e bakınız).
Bellek parçalanması, boş hafıza varken bile takas kullanımının artmasının bir nedenidir.