Linux çekirdeğinin bellek sınırı


12

Şaşırtıcı bir sorunum var. Özelleştirilmiş CDB'leri yürütmek için sg kullanan bir kütüphane var . Rutin bellek tahsisi ile ilgili sorunlar sistemlerinin bir çift vardır sg . Genellikle, sg sürücüsünün sabit limiti yaklaşık 4mb'dir, ancak ~ 2.3mb istekleri olan bu birkaç sistemde görüyoruz. Yani, CDB'ler 2.3mb aktarım için tahsis etmeye hazırlanıyor. Burada herhangi bir sorun olmamalıdır: 2.3 <4.0.

Şimdi, makinenin profili. 64 bit CPU'dur, ancak CentOS 6.0 32 bit'i çalıştırır (bunları oluşturmadım veya bu kararla ilgim yok). Bu CentOS dağıtımının çekirdek sürümü 2.6.32'dir. 16GB RAM'e sahipler.

İşte sistemde gibi bellek kullanımı görünüyor (bu hata otomatik test sırasında meydana çünkü bu errno döndürülür durumunu yansıtır eğer olsa da, henüz doğrulanmadı da budur sg ).

top - 00:54:46 up 5 days, 22:05,  1 user,  load average: 0.00, 0.01, 0.21
Tasks: 297 total,   1 running, 296 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  15888480k total,  9460408k used,  6428072k free,   258280k buffers
Swap:  4194296k total,        0k used,  4194296k free,  8497424k cached

Bulduğum bu yazıyı gelen Linux Journal çekirdeğindeki bellek ayrılırken hakkındadır. Makale tarihli ama 2.6 ile ilgili görünüyor (baştaki yazar hakkında bazı yorumlar). Makale, çekirdeğin yaklaşık 1 gb bellekle sınırlı olduğunu belirtiyor (ancak fiziksel ve sanal veya toplam için 1 gb ise metinden tamamen açık olmasa da). Bunun 2.6.32 için doğru bir ifade olup olmadığını merak ediyorum. Sonuçta, bu sistemlerin bu sınıra ulaşıp ulaşmadığını merak ediyorum.

Bu benim problemime gerçekten bir cevap olmasa da, 2.6.32 iddiasının doğruluğunu merak ediyorum. Öyleyse, çekirdek için gerçek bellek sınırı nedir? Sorun giderme için bunun dikkate alınması gerekebilir. Diğer önerilerinizi bekliyoruz. Bunu bu kadar şaşırtıcı yapan şey, bu sistemlerin aynı sorunu göstermeyen diğer birçok sistemle aynı olmasıdır.

Yanıtlar:


21

32 bit sistemde Linux çekirdek belleği için 1 GiB sınırı, 32 bit adreslemenin bir sonucudur ve oldukça sert bir sınırdır. Değiştirmek imkansız değil, ama çok iyi bir nedenden dolayı orada; değiştirmenin sonuçları vardır.

Geri dönüş makinesini Linux'un yaratıldığı 1990'ların başına götürelim. O günlerde, Linux'un 2 MiB RAM'de çalıştırılmak için yapılabileceği veya gerçekten 4 tam MiB'ye ihtiyacı olup olmadığı konusunda tartışmalarımız olacaktı . Tabii ki, üst düzey züppe 16 MiB canavar sunucusu ile hepimiz alay ediyordu.

Eğlenceli küçük vinyetin herhangi bir şeyle ne ilgisi var? Bu dünyada, basit 32 bit adreslemeden aldığınız 4 GiB adres alanının nasıl bölüneceği hakkında karar vermek kolaydır. Bazı işletim sistemleri, adresin üst bitini "çekirdek bayrağı" olarak ele alarak sadece ikiye böldü: 0 ile 2 31 -1 arasındaki adresler en üst biti temizledi ve kullanıcı alanı kodu içindi ve 2 31 ile 2 32 arasındaki adresler - 1 üst biti ayarlanmıştı ve çekirdek içindi. Sadece adrese bakıp şunu söyleyebilirsiniz: 0x80000000 ve üstü, çekirdek alanı, aksi takdirde kullanıcı alanı.

PC bellek boyutları bu 4 GiB bellek sınırına doğru arttıkça, bu basit 2/2 bölünmesi sorun olmaya başladı. Kullanıcı alanı ve çekirdek alanı, çok fazla RAM konusunda iyi iddialara sahipti, ancak bir bilgisayara sahip olma amacımız, çekirdek çalıştırmak yerine genellikle kullanıcı programlarını çalıştırmak olduğundan, işletim sistemleri kullanıcı / çekirdek bölünmesiyle oynamaya başladı. 3/1 ayrımı yaygın bir uzlaşmadır.

Fiziksel ve sanal hakkında sorunuza gelince, aslında önemli değil. Teknik olarak konuşursak, bu sanal bir bellek sınırıdır, ancak bunun nedeni Linux'un VM tabanlı bir işletim sistemi olmasıdır. 32 GiB fiziksel RAM takmak hiçbir şeyi değiştirmez swaponve 32 GiB takas bölümüne yardımcı olmaz. Ne yaparsanız yapın, 32 bit Linux çekirdeği aynı anda asla 4 GiB'den fazlasını ele alamaz.

(Evet, PAE'yi biliyorum . Şimdi 64 bit işletim sistemleri nihayet devralıyor, umarım bu kötü hack'i unutmaya başlayabiliriz. Yine de bu durumda size yardımcı olabileceğine inanmıyorum.)

Sonuç olarak, 1 GiB çekirdek VM sınırına giriyorsanız, çekirdeği 2/2 bölünmeyle yeniden oluşturabilirsiniz, ancak bu doğrudan kullanıcı alanı programlarını etkiler.

64-bit gerçekten doğru cevaptır.


1
Teşekkürler. Bu yazı harika. Windows'da yaygın olarak kullanılan 2/2 bölmesine girdim. O zaman, Linux'un 3/1 ayrımı kullandığını öğrendim. Makaleyi okurken, noktaları birleştirebileceğimi düşünmüş olsaydım. Yani ... bu aklımda tutmam gerekecek gibi görünüyor. Muhtemelen bu sistemlerin testlerin doğası göz önünde bulundurularak sınırlara ulaştığını düşünmek mümkün değildir. Büyük soru, neden diğer sistemler de bunu yaşamıyor. Tekrar teşekkürler.
Andrew Falanga

1
@AndrewFalanga: Aslında, modern Windows da bulanık bir 3/1 bölmesi kullanıyor .
Warren Young

1
Bazılarımız 12 MB'lık bir sunucu almak için SSC'den miras alınan üç farklı makinenin belleğini birleştirebildik. Yani çok biz istediğimiz bir şey yapabileceğini hafıza ...
dmckee --- eski moderatör yavru

3
"Evet, x86 bölümlü bellek modelini biliyorum . Şimdi 32 bit işletim sistemleri nihayet devralıyor, umarım bu kötü hack'i unutmaya başlayabiliriz."
CVn

32 ve 64 bit arasında 16 ve 32 arasında iki kat daha fazla çiftleme vardır, bu da bu tür saldırıları ertelememiz gereken süreyi iki katına çıkarır, her şey eşittir. Ama diğer her şey eşit değil , Moore Yasası'nın gün batımıyla ne. 32-bit x86 bilgi işlemden yirmi yıl geçirdik. Biz alabilirsiniz yüzyıllar 64 bit dışarı. Günümüz DRAM bant genişliklerinde 2⁶⁴ bayt RAM'in tek geçişli okunması yaklaşık 30 yıl alacaktır . 64 bit sınırına yaklaşmamızı sağlamak için bant genişliği artışı nereden gelecek?
Warren Young

2

Warren Young'ın mükemmel cevabına biraz eklemek istiyorum , çünkü işler aslında yazdıklarından daha kötü.

1 GB'lık çekirdek adres alanı iki bölüme ayrılmıştır. 128MB için vmallocve 896MB için lowmem. Aslında ne anlama geldiğini boş ver. Bellek tahsis ederken, çekirdek kodu bunlardan hangisini istediğini seçmelidir. Hangi havuzda boş alan varsa sadece bellek alamazsınız.

İsterseniz vmalloc128 MB ile sınırlısınız. Şimdi 1GB çok kötü görünmüyor ...

İsterseniz lowmem896 MB ile sınırlısınız. 1GB'dan çok uzak değil, ancak bu durumda, tüm ayırmalar 2'nin bir sonraki gücüne yuvarlanır. Yani 2.3MB'lık bir ayırma aslında 4MB tüketir. Ayrıca, kullanırken tek bir çağrıda 4 MB'tan fazla veri ayıramazsınız lowmem.

64-bit gerçekten doğru cevaptır.


Cevabınızla ilgili bir sorum var. Lowmem adlı bu bellek alanı için, kmalloc ve kzmalloc gibi çağrılardan gelen bellek nereden geliyor?
Andrew Falanga

@AndrewFalanga, evet, bu işlevler lowmem kullanır.
ugoren
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.