Sızan bellek neden kernel_task için hatalı görünüyor ve neden OS X çöpü toplayamıyor


11

Daha önce, bazı uygulamaların bellek sızıntısı olduğuna dair bir işaretin kernel_task, genellikle gigabayt sırasına göre geniş bir bellek alanına sahip olduğu söylendi . Bir ters Eğer kextbu bellek kullanımını neden oldu, biz ayrılan bellek ve tahsis edilmesi bekleniyor olanlar, yani arasında bir tutarsızlık görmeyi bekleriz

diff <(kextstat|tr -s ' ' | cut -d ' ' -f 5) <(kextstat| tr -s ' ' | cut -d ' ' -f 6) 

"Kablolu" ve "Ad" sözcüklerinden başka bir şey döndürür.

Tezimi yazarken, Önizleme'de açıkken bir pdf değiştirmenin çoğu zaman kötü şeylerin gerçekleşmesine neden olduğunu fark ettim: zaman zaman, bellek kullanımının kernel_taskyaklaşık sekiz gigabayta veya daha fazlasına çıkabileceğini. Önizlemeyi öldürürsem, anında normale döner . Açıkçası, bir şeyler yanlış - ve Önizleme bu koşullar altında bellek sızdırıyor.

Yani, sorum şu: eğer ben bir süreçtir ait ayak izi ani ve beklenmedik artış yoluyla koç sızdırılmış olduğunu biliyor kernel_tasknedeninizi OS X bir şeyin gitmiş yanlış olduğunu biliyorum. Önizleme öldürme benim eksik geri gelmesini malloc()d hafızası', neden vermez Darwin benim için automagicallylar çöp toplama mı?

Bellek yönetiminin nasıl çalıştığı hakkında temel bir yanlış anlama var mı?

DÜZENLEME: (15/9/15)

İşte neden bahsettiğimi gösteren bir gösteri. Her şeyden önce, yüksek bellek kullanımını fark ediyorum kernel_task(333 MiB ram kullanarak, Etkinlik Monitörünün altında görülebilir, Önizleme açıktır):

Yüksek çekirdek belleği kullanımı

Aşağıdaki Ashley tarafından yapılan faydalı açıklamalardan sonra, her bir kext'in ne kadar kullandığını öğrenelim:

$ kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n

...
...
...
   1249280 com.apple.driver.DspFuncLib
   1769472 com.apple.nvidia.driver.NVDAGK100Hal
   2629632 com.apple.nvidia.driver.NVDAResman
   6184960 com.apple.driver.AirPort.Brcm4360
$

Yani, büyük bir miktar değil. Makinemde hem ayrık hem de entegre GPU'lar var; sürücüleri sadece birkaç MiB kablolu koç kullanıyor. Önsezimde, Önizlemeyi öldürelim ve şunların bellek ayak izine ne olduğuna bakalım kernel_task:

Öldürme önizlemesi işlere yardımcı olur

Önizleme gitti ve çekirdeğin bellek ayak izi önemli ölçüde azaldı. Kext kullanımında bir değişiklik olduğuna dair hala bir kanıt yok: yukarıdaki komutun çıktısı değişmedi.

Düzenleme : Hata No. 22701036 olarak bildirdi. Hala elma bir yanıt bekliyorum. ActivityMonitor'daki süreci incelerseniz özellikle ilginç bir şey yok, ama belki bir şey eksik.


İki şey hakkında kafam karıştı - açıklığa kavuşturabilir misiniz? 1) diffKomutunuzun çıktıdaki Sizeve Wiredsütunlarını karşılaştırdığını düşünüyorum kextstat. Size"Ayrılmış bellek" olduğunu kabul ediyorum , ama "ayrılması Wiredbekleniyor" olduğunu sanmıyorum ( man kextstat"kext kapladığı çekirdek belleğin kablolu bayt sayısı" olarak açıklar). 2) Önizleme ile ilgili sorun arasında Sizeve Wiredne zaman tutarsızlık olduğunu görüyor musunuz ?
Ashley

1) Haklısın - Boyut ve Kablolu öğelerini karşılaştırıyorum kextstat. Anladığım kadarıyla bir kext sızıyorsa, tahsis edilen baytlar ve çekirdeğin tahsis edildiğini bildikleri farklı olacaktır. Bu durumda, oraya sızdıran bir ipucum olmadığını göstermek için koydum - bu yüzden, 2) Önizleme koç yendiğinde bu gerçekleşmez. Bunun yerine, kernel_taskçok büyür. Bu sorunu yeniden oluşturmaya ve bir resim çekmeye çalışacağım :-).
Landak

Teşekkürler! Bir saniye bekle: Sadece yardımcı olabilecek bir cevap yazıyorum.
Ashley

Yanıtlar:


6

OS X çekirdek çöp toplama değildir; IOKit en libkern C ++ çalışma zamanı kendi belleği yönetmek için geliştiriciler gerektirir.

Mac Bellek Yönetimi

Kimden Mac OS X'te bellek yönetimi nasıl çalışır?

Apple, Mach Çekirdeğinin ve sanal bellek alt sisteminin en düşük düzeylerini geliştirici belgelerinin bir parçası olarak web üzerinde oldukça iyi belgeliyor.

Bu çekirdek Carnegie Mellon Üniversitesi tarafından geliştirildiğinden , onu kolayca tanımlayan düzinelerce kağıt bulabilirsiniz .

Diğer kaynaklar

Çöp toplama

Çöp toplama kullanıcı veya uygulama katmanında bulunur. Bu katmanda bile, çöp toplama işlemi yalnızca uygulamanın tüm hak taleplerini belleğe bırakması durumunda yardımcı olur. Dairesel bir bağımlılık çöp toplamayı yenebilir. Çöp toplamanın kendisi gelişen bir araştırma alanıdır ve doğru yapılması zordur .

Hataları ve Bellek Sızıntılarını Bildirin

OS X içindeki hatalar bellek sızdırıyor. Kod tabanının boyutu göz önüne alındığında, bu neredeyse kesindir.

Lütfen tekrarlanabilir hataları doğrudan Apple'a bildirin . Her hata raporu yardımcı olur ve belki de Apple mühendislerinin nedeni tespit etmesine yardımcı olacak örnek olabilir.


Bu hayal kırıklığı yaratıyor, ancak şüphesiz doğru. Hatayı Apple'a bildirdim - sadece sinir bozucu buluyorum!
Landak

2
Lütfen hata numarasını sorunuzun bir düzenlemesi olarak paylaşabilirsiniz. Sorunuzu faydalı bulan diğer kullanıcılar, orijinalinizi belirten yinelenen hatalar oluşturabilir. İlgili hataların yığını daha fazla mühendislik süresini haklı çıkarmaya yardımcı olacaktır.
Graham Miln

4

Tahminime göre, Mac'inizde entegre bir GPU (örn. Intel Iris Graphics) olduğunu varsayalım.

Tezinizi Önizleme'de açtığınızda, grafik kartı belleği, Önizleme penceresinin görüntüsünü ("doku") ve belki de tezden ekran dışı ancak kodu çözülmüş bazı sayfaları tutmak için kullanılır.

Tümleşik bir grafik kartıyla video belleği aslında (kısmen?) CPU ve GPU arasında paylaşılan sistem RAM'inde bulunur. Bazı tümleşik grafik kartlarında, kullanılan sistem RAM miktarı dinamik olarak ayrılır (bkz. Apple HT204349 ).

Grafik kartı sürücüsünde ve / veya Önizlemede aralıklı olarak bir hata gördüğünüzü tahmin ediyorum. (Ancak bu hata OS X / sürücü tarafından Önizleme sona erdiğinde belleği doğru şekilde serbest bırakır.)

Çıktıya bakmayı deneyebilir ve sorunla karşılaştığınızda sütundaki kextstatsayıların Sizeartıp artmadığını görebilirsiniz . Benim teorim, bahsettiğiniz 8GB'lık artışın grafik kartı sürücüsüne bağlı olacağı.

(Yorumunda aşağıdaki komutu bu ilgili ve ilginç cevap ) çıktısını sıralar kextstatdaha kolay tarafından (not rağmen bu türlü en bellek kullandığını hangi kext görmek yapmak için Wiredbenzer bir basit büyü içinde var ... sütununda bu eğer bunu ayarlamak isterseniz bir açıklama ile cevaplayınız ).

kextstat | awk 'NR==1{ printf "%10s %s\n", $5, $6; } NR!=1{ printf "%10d %s\n", $5, $6; }' | sort -n

İyi tahmin - ve yararlı, sıralı bir çıktı için çok teşekkür ederim kextstat. Bununla birlikte, hala gerçekte olan şey gibi görünmüyor: Önizleme-gobbling sırasında, bellek ayak izi com.apple.nvidia.driver.*değişmedi. Sorumu bunu yansıtacak şekilde düzenledim.
Landak
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.