Dosyalar RAM'e yüklenen işlemler tarafından açılıyor mu?


24

Komutlar , örneğin sed, programlar ve programlar bir dosyanın içinde kodlanmış bir mantıktır ve bu dosyalar sabit diskte bir yerdedir. Ancak komutlar çalıştırılırken, sabit diskten dosyalarının bir kopyası , hayata geçtiği ve bir şeyler yapabilecekleri ve işlem adı verilen RAM'e konur .

İşlemler diğer dosyaları kullanabilir, okuyabilir veya bunlara yazabilir ve bu dosyaları yaparlarsa açık dosya olarak adlandırılırlar. Çalışan tüm işlemler tarafından tüm açık dosyaları listelemek için bir komut vardır: lsof.

Tamam, merak ettiğim şey bir komutun çifte ömrünün biri sabit diskte, RAM'de diğeri de başka tür dosyalar için geçerli olup olmadığıdır, örneğin programlanmış mantığı olmayan, ancak sadece kapsayıcı olan veri.

Benim varsayım, işlemler tarafından açılan dosyaların da RAM'e yüklendiğidir. Bunun doğru olup olmadığını bilmiyorum, sadece bir sezgi.

Lütfen, birileri anlayabilir mi?


Yanıtlar:


27

Ancak komutlar çalıştırıldığında, dosyalarının bir kopyasını sabit diskten RAM’e koyar,

Bu yanlış (genel olarak). Bir program yürütüldüğünde ( yürütme (2) ...) işlem (bu programı çalıştıran) sanal adres alanını değiştirir ve çekirdek MMU'yu bu amaç için yeniden yapılandırır . Ayrıca sanal bellek hakkında da bilgi edinin . Uygulama programlarının sanal adres alanlarını , dinamik bağlayıcı tarafından da kullanılan mmap (2) & munmap& mprotect (2) kullanarak değiştirebildiğine dikkat edin (bkz. Ld-linux (8) ). Ayrıca bakınız madvise (2) & posix_fadvise (2) ve mlock (2) .

Gelecek sayfa hataları , yürütülebilir dosyadan (lazily) sayfaları yüklemek için çekirdek tarafından işlenecektir. Thrashing hakkında da okuyun .

Çekirdek büyük bir sayfa önbelleği tutar . Yazma üzerine de oku . Ayrıca bkz. Okuma kafası (2) .

Tamam, merak ettiğim şey bir komutun çifte ömrünün biri sabit diskte, RAM'de diğeri de başka tür dosyalar için geçerli olup olmadığıdır, örneğin programlanmış mantığı olmayan, ancak sadece kapsayıcı olan veri.

İçin sistem çağrıları gibi okuma (2) ve yazma (2) sayfa önbellek de kullanılır. Okunacak veriler içeride oturuyorsa, disk GÇ işlemi yapılmayacaktır. Eğer disk IO'su gerekliyse, okuma verileri büyük olasılıkla sayfa önbelleğine alınacaktır. Bu nedenle, pratikte, aynı komutu iki kez çalıştırırsanız, ikinci kez diske hiçbir fiziksel G / Ç yapılmadığı ortaya çıkabilir (eski bir sabit diskiniz varsa - SSD değil - bunu duyabilirsiniz); veya sabit disk LED'inizi dikkatlice izleyin).

Tüm bunları açıklayan, İşletim Sistemleri: Üç Kolay Parça (ücretsiz indirilebilir, bölüm başına bir PDF dosyası) gibi bir kitap okumanızı öneririm .

Ayrıca bakınız Linux My RAM Ate gibi ve çalıştırma komutları xosview, top, htopveya cat /proc/self/mapsveya cat /proc/$$/maps(bkz proc (5) ).

PS. Linux'a odaklanıyorum, ancak diğer işletim sistemlerinde de sanal bellek ve sayfa önbelleği var.


35

Hayır, bir dosya açılarak otomatik olarak belleğe okunmaz. Bu çok verimsiz olurdu. sedÖrneğin, birçok diğer Unix aracında olduğu gibi giriş satırını satır satır okur. Nadiren mevcut satırdan daha fazlasını bellekte tutması gerekir.

Bununla awkaynı. Her seferinde bir kaydı okur , bu varsayılan olarak bir çizgidir. Giriş verilerinin bölümlerini değişkenlerde saklarsanız, bu elbette 1 olacaktır .

Bazı insanlar gibi şeyler yapma alışkanlığı var

for line in $(cat file); do ...; done

Kabuğun $(cat file), fordöngünün ilk yinelemesini bile çalıştırmadan önce komut ikamesini tamamen genişletmesi gerekeceğinden , bu işlem bütünün filebelleğini okuyacak ( fordöngüyü çalıştıran kabuk tarafından kullanılan belleğe ). Bu biraz saçma ve aynı zamanda inelegant. Bunun yerine, kişi yapmalı

while IFS= read -r line; do ...; done <file

Bu filesatır satır işleyecektir (ancak "IFS = read -r line" ı Anlamak bölümünü oku ).

Dosyaların satır satır satır işlenmesi, çoğu yardımcı program zaten satır yönelimli olduğundan, ancak nadiren ihtiyaç duyulur (bkz. Neden kötü uygulama olarak kabul edilen metni işlemek için bir kabuk döngüsü kullanıyorsunuz? ).

Biyoinformatikte çalışıyorum ve çok büyük miktarlarda genomik veri işlerken, sadece bellekte kesinlikle gerekli olan verilerin parçalarını tutmadığım sürece pek bir şey yapamayacağım. Örneğin, bir VCF dosyasındaki DNA varyantlarını içeren 1 terabaytlık bir veri kümesinden bireyleri tanımlamak için kullanılabilecek veri parçalarını çıkarmam gerektiğinde (bu tür verilerin halka açık hale getirilememesi nedeniyle) satır satır yapıyorum Basit bir awkprogramla işleme (VCF formatı satır yönelimli olduğu için mümkündür). Ben yok , belleğe dosyayı okumak onu orada işlemek ve tekrar vazgeçme yazın! Dosya sıkıştırılmış olsaydı, onu beslerdim zcatya da verilerin akışını işleme koyduğundan gzip -d -cberi gziptüm dosyayı da belleğe okumazdı.

JSON veya XML gibi satır yönelimli olmayan dosya biçimlerinde bile, büyük dosyaları hepsini RAM'de saklamaksızın işlemeyi mümkün kılan akış ayrıştırıcıları vardır.

Yürütülebilir dosyalarda, paylaşılan kitaplıklar isteğe bağlı olarak yüklenebildiğinden ve / veya işlemler arasında paylaşılabildiğinden biraz daha karmaşıktır ( örneğin, paylaşılan kitaplıkların yüklenmesi ve RAM kullanımı gibi).

Önbellekleme burada bahsetmediğim bir şey. Bu, sık erişilen veri parçalarını tutmak için RAM kullanma eylemidir. Daha küçük dosyalar (örneğin yürütülebilir dosyalar), kullanıcının kendilerine birçok referans yapması umuduyla OS tarafından önbelleğe alınabilir. Dosyanın ilk okunmasından ayrı olarak, daha sonra disk yerine RAM'e erişilir. Önbelleğe alma, giriş ve çıktının tamponlanması gibi, genellikle kullanıcı için büyük ölçüde şeffaftır ve uygulamaları önbelleğe almak için kullanılan bellek miktarı, uygulamalar vb. Tarafından tahsis edilen RAM miktarına bağlı olarak dinamik olarak değişebilir.


1 Teknik olarak, çoğu program muhtemelen açık ara belleğe kullanarak veya örtülü olarak standart G / Ç kütüphaneleri yapmak arabelleğe yoluyla ve sonra, ya bir defada girdi Veri yığınının okumak kullanıcının koduna çizgiyle yığın hattı söyledi. Diskin blok boyutunun birçoğunu okumak, her seferinde bir karakterden çok daha verimlidir. Bu yığın boyutu nadiren bir avuç kilobayttan daha büyük olacaktır.


paylaşılan kütüphaneleri RAM’e yüklemek mümkün, dediniz ki, RAM’e yalnızca veri içeren normal bir dosyayı yüklemek mümkün olsa da?
sharkant

1
@sharkant Elbette. Bu, yalnızca tüm dosya saklanana kadar bir değişkene (veya diziye veya karma değere veya söz konusu sarf malzemelerinin dilini ne tür bir yapıya sokarsa) veri ekleme meselesidir. İle awk, { a[i++] = $0 }diziye girdi dosyasının tüm satırları eklersiniz a. Ayrıca C işlevine de bakmak isteyebilirsiniz mmap(), ancak kullanımı burada konu dışı olabilir.
Kusalananda

6
sed, awkve diğer satır yönelimli programlar bir seferde belleğe satır okumaz, çünkü düz metin dosyaları satır dizini içermez ve dosya sistemi API'leri ve düşük düzey depolama donanımı bir veya daha fazla "sektör" okur (tipik olarak 512) veya bir kerede 1024 bayt). İlk satır işlenmeden önce işletim sistemi tarafından 8KB'den daha azının hafızaya okunması beni şaşırttı.
Russell Borogove

5
Gibi bir yardımcı program sedher seferinde yalnızca bir satırı belleğe okuyacak olsa da, işletim sisteminin hızlı bir şekilde erişebilmeleri için dosyaları önbelleğe almak için serbest ram kullanacağını belirtmekte fayda vardır. Daha sedküçük bir dosya üzerinde çalışıyorsanız , işletim sisteminin tüm dosyayı bellekte önbelleğe alacağı ve işlemin tamamen RAM'de yapılması mümkün olabilir. Bakınız: en.wikipedia.org/wiki/Page_cache
Sean Dawson,

5
@sharkant Bir dosyanın belleğe tamamen erişilebilmesi için kullanılır (diğer cevaba bakınız, mmap burada anahtar kelime sistemi çağrısıdır). Örneğin, bir veritabanı sistemi genellikle erişim kolaylığı ve hızı için tüm veritabanına veya en azından belleğe eşlenmiş endekslerden bazılarına sahip olmak ister. Bu mutlaka her şeyin aslında bellekte olduğu anlamına gelmez. İşletim sistemi, dosyanın bellekte olduğunu iddia etmekte özgürdür. Uygulamaya, "burada, bu aralıktaki bellekte sizin dosyanız" dır.
Jonas Schäfer

5

Hayır. Bugünlerde çok sayıda RAM almak harika olsa da, RAM'in çok sınırlı bir kaynak olduğu (2 VA RAM ile VAX 11/750'de programlama öğrendim) ve RAM'deki tek şey aktif olarak yürütülebilir sayfalardı. işlemlerin ve arabellek önbelleğindeki dosya verilerinin açıklaması.
Tampon önbellek temizlendi ve veri sayfaları değiştirildi. Ve bazen de sık sık. Salt okunur çalıştırılabilir sayfaların üzerine yazılmış ve sayfa tabloları işaretlenmiş, böylece program bu sayfalara tekrar dokunduğunda dosya sisteminden çağrılmıştır. Veri takas alanından kaydedildi. Yukarıda da belirtildiği gibi, STDIO kütüphanesi veriyi bloklar halinde çekti ve gerektiğinde program tarafından elde edildi: fgetc, fgets, fread, vb. Mmap ile bir dosya ile yapılan gibi bir işlemin adres alanına eşlenebilir. paylaşılan kütüphane nesneleri veya hatta normal dosyalar. Evet, RAM'de ise (mlock) yoksa bir dereceye kadar kontrolünüz olabilir, fakat sadece o kadar ileri gider (mlock'un hata kodu bölümüne bakınız).


1
"RAM'iniz dosyalarınız için çok küçük olacak" ifadesi VAX’ın eski günlerinde olduğu gibi doğru.
Federico Poloni

1
@ Federico_Poloni Bugün pek doğru değil. Son işverenimde 1 TB RAM ve sadece 0,5 TB sabit diskli bir iş istasyonu sınıfı bilgisayarımız vardı. (Problem sınıfı: küçük girdiler, orta çıktılar, hesaplama sırasında rastgele erişilen büyük diziler).
nigel222
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.