เหตุใดหน่วยความจำที่รั่วไหลจึงปรากฏ malloced ไปที่ kernel_task และทำไม OS X จึงไม่สามารถรวบรวมขยะได้


11

ก่อนหน้านี้ฉันได้รับแจ้งว่ามีสัญญาณว่าบางแอปพลิเคชันมีหน่วยความจำรั่วนั่นคือkernel_taskมีหน่วยความจำขนาดใหญ่ตามลำดับหน่วยเป็นกิกะไบต์ หากมีข้อผิดพลาดkextทำให้การใช้งานหน่วยความจำนี้เราคาดว่าจะเห็นความแตกต่างระหว่างหน่วยความจำที่จัดสรรและที่คาดว่าจะได้รับการจัดสรรคือ

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

จะส่งคืนสิ่งอื่นนอกเหนือจากคำว่า 'Wired' และ 'Name'

ในขณะที่เขียนวิทยานิพนธ์ของฉันฉันสังเกตเห็นว่าการเปลี่ยนไฟล์ PDF ในขณะที่เปิดอยู่ในหน้าตัวอย่างมักจะทำให้สิ่งเลวร้ายเกิดขึ้น: บางครั้งการใช้หน่วยความจำของkernel_taskสามารถเติบโตถึงประมาณแปดกิกะไบต์หรือมากกว่า ถ้าฉันฆ่าภาพตัวอย่างก็จะกลับสู่ปกติได้ทันที เห็นได้ชัดว่ามีบางอย่างผิดปกติและพรีวิวกำลังรั่วหน่วยความจำภายใต้เงื่อนไขเหล่านี้

ดังนั้นคำถามของฉันคือ: ถ้าฉันรู้ว่ากระบวนการรั่ว ram ผ่านการเพิ่มขึ้นอย่างกะทันหันและคาดไม่ถึงkernel_taskทำไมOS Xจึงไม่สามารถรู้ได้ว่ามีบางอย่างผิดปกติ ถ้าฆ่าดูตัวอย่างเรียกคืนของฉันหายไปmalloc()'d หน่วยความจำทำไมไม่ดาร์วินทำเก็บขยะโดยอัตโนมัติสำหรับฉันหรือไม่

ฉันมีความเข้าใจผิดพื้นฐานเกี่ยวกับการจัดการหน่วยความจำหรือไม่

แก้ไข: (15/9/15)

นี่คือการสาธิตสิ่งที่ฉันพูดถึง ก่อนอื่นฉันสังเกตเห็นการใช้หน่วยความจำสูงด้วยkernel_task(หมายเหตุเปิดตัวอย่างอยู่ที่ด้านล่างของ Activity Monitor โดยใช้ ram 333 MiB):

การใช้หน่วยความจำเคอร์เนลสูง

ทำตามคำพูดที่เป็นประโยชน์โดยแอชลีย์ด้านล่างเรามาดูกันว่า kext แต่ละตัวใช้งานอะไรกัน:

$ 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
$

ดังนั้นไม่ใช่จำนวนมาก เครื่องของฉันมีทั้ง GPU แยกและรวม ไดรเวอร์ของพวกเขาใช้เพียง RAM MiB เพียงไม่กี่สาย ในลางสังหรณ์ของฉันลองมาดูตัวอย่างและดูว่าเกิดอะไรขึ้นกับรอยความทรงจำของkernel_task:

ดูตัวอย่างการฆ่าช่วยได้

หน้าตัวอย่างหายไปและรอยความทรงจำของเคอร์เนลลดลงอย่างมาก ยังไม่มีหลักฐานการเปลี่ยนแปลงการใช้งาน kext: ผลลัพธ์ของคำสั่งด้านบนไม่เปลี่ยนแปลง

แก้ไข : รายงานข้อผิดพลาดเป็นหมายเลข 22701036 ฉันยังคงรอการตอบสนองจากแอปเปิ้ล ไม่มีอะไรน่าสนใจเป็นพิเศษหากคุณตรวจสอบกระบวนการใน ActivityMonitor แต่บางทีฉันอาจพลาดอะไรบางอย่าง


ฉันสับสนเกี่ยวกับสองสิ่ง - คุณช่วยอธิบายได้ไหม 1) ฉันคิดว่าdiffคำสั่งของคุณกำลังเปรียบเทียบSizeและWiredคอลัมน์จากkextstatผลลัพธ์ ฉันยอมรับว่าSizeเป็น "หน่วยความจำที่จัดสรร" แต่ฉันไม่คิดว่าWiredเป็น "คาดว่าจะได้รับการจัดสรร" ( man kextstatอธิบายว่า "จำนวนไบต์ต่อสายของหน่วยความจำเคอร์เนลที่ kext ใช้") 2) คุณเห็นความแตกต่างระหว่างSizeและWiredเมื่อคุณมีปัญหากับหน้าตัวอย่างหรือไม่
แอชลีย์

1) คุณขวา - kextstatฉันกำลังเปรียบเทียบองค์ประกอบในขนาดและแบบใช้สายจาก ความเข้าใจของฉันคือถ้าkextรั่วแล้วไบต์ที่ปันส่วนและเคอร์เนลที่รู้ถูกจัดสรรจะแตกต่างกัน ในกรณีนี้ฉันวางไว้ตรงนั้นเพื่อแสดงว่าฉันไม่มี kext ที่รั่ว - ดังนั้น 2) สิ่งนี้จะไม่เกิดขึ้นเมื่อ Preview กิน ram แทนที่จะkernel_taskเติบโตขึ้นมาก ฉันจะพยายามสร้างปัญหานี้ขึ้นใหม่และถ่ายรูป :-)
Landak

ขอบคุณ! รอสักครู่: ฉันแค่เขียนคำตอบที่อาจช่วยได้
แอชลีย์

คำตอบ:


6

หลักของ OS Xไม่เก็บขยะ; รันไทม์C ++ของ IOKit ของIOKitต้องการผู้พัฒนาเพื่อจัดการหน่วยความจำของตนเอง

การจัดการหน่วยความจำ Mac

จากวิธีการทำงานจัดการหน่วยความจำใน Mac OS X?

Apple บันทึกระดับที่ต่ำที่สุดของMach Kernelและระบบย่อยหน่วยความจำเสมือนบนเว็บค่อนข้างดีซึ่งเป็นส่วนหนึ่งของเอกสารประกอบสำหรับนักพัฒนา

เนื่องจากเคอร์เนลนั้นได้รับการพัฒนาโดย Carnegie Mellon Universityคุณสามารถค้นหาเอกสารจำนวนมากที่อธิบายได้อย่างง่ายดาย

แหล่งข้อมูลอื่น ๆ

เก็บขยะ

มีการรวบรวมขยะที่ผู้ใช้หรือชั้นแอปพลิเคชัน แม้ในชั้นนี้การรวบรวมขยะจะช่วยได้ก็ต่อเมื่อแอปพลิเคชันปล่อยการอ้างสิทธิ์ทั้งหมดไปยังหน่วยความจำ การพึ่งพาแบบวงกลมสามารถเอาชนะการเก็บขยะได้ เก็บขยะตัวเองเป็นพื้นที่การพัฒนาของการวิจัยและยากที่จะได้รับสิทธิ

รายงานข้อบกพร่องและการรั่วไหลของหน่วยความจำ

ข้อบกพร่องใน OS X จะทำให้หน่วยความจำรั่ว เมื่อพิจารณาขนาดของฐานรหัสแล้วนี่เกือบจะแน่นอน

กรุณารายงานข้อผิดพลาดที่ทำซ้ำได้โดยตรงกับแอปเปิ้ล รายงานข้อผิดพลาดทุกรายการจะช่วยและตัวอย่างของคุณอาจเป็นรายงานที่ช่วยวิศวกรของ Apple ระบุสาเหตุ


มันน่าผิดหวัง แต่ก็ถูกต้องอย่างแน่นอน ฉันรายงานข้อผิดพลาดไปยัง Apple - ฉันเพิ่งพบว่ามันน่ารำคาญ!
Landak

2
กรุณาคุณสามารถแบ่งปันหมายเลขข้อผิดพลาดเป็นการแก้ไขคำถามของคุณ ผู้อื่นที่ค้นหาคำถามของคุณมีประโยชน์สามารถส่งไฟล์บั๊กที่ซ้ำกันซึ่งสังเกตเห็นต้นฉบับของคุณ กองข้อบกพร่องที่เกี่ยวข้องจะช่วยปรับเวลาวิศวกรรมเพิ่มเติม
เกรแฮมมิลน์

4

นี่คือการคาดเดาของฉันสมมติว่า Mac ของคุณมี GPU ในตัว (เช่น Intel Iris Graphics)

เมื่อคุณเปิดวิทยานิพนธ์ของคุณในหน้าตัวอย่างจะใช้หน่วยความจำกราฟิกการ์ดเพื่อเก็บรูปภาพ ("พื้นผิว") ของหน้าต่างแสดงตัวอย่างและอาจมีบางหน้านอกหน้าจอ แต่ถอดรหัสจากวิทยานิพนธ์

เมื่อใช้การ์ดกราฟิกในตัวหน่วยความจำวิดีโอจะอยู่ในระบบ RAM ซึ่งใช้ร่วมกันระหว่าง CPU และ GPU ในกราฟิกการ์ดรวมบางตัวปริมาณของ RAM ระบบที่ใช้ถูกจัดสรรแบบไดนามิก (ดูApple HT204349 )

ฉันเดาว่าคุณเห็นข้อผิดพลาดเป็นระยะ ๆ ในไดรเวอร์การ์ดแสดงผลและ / หรือดูตัวอย่างซึ่งไม่ปล่อยหน่วยความจำระบบอย่างถูกต้องเมื่อดูตัวอย่างโหลดวิทยานิพนธ์ PDF ของคุณอีกครั้ง (อย่างไรก็ตามข้อผิดพลาดนี้ได้รับการลดทอนโดย OS X / ไดร์เวอร์ที่ปล่อยหน่วยความจำอย่างถูกต้องเมื่อดูตัวอย่างออก)

คุณสามารถลองดูผลลัพธ์ของkextstatและดูว่าตัวเลขในSizeคอลัมน์เพิ่มขึ้นเมื่อคุณพบปัญหาหรือไม่ ทฤษฎีของฉันคือการเพิ่ม 8GB ที่คุณพูดถึงจะเป็นเพราะไดรเวอร์การ์ดแสดงผล

คำสั่งดังต่อไปนี้ (จากความคิดเห็นในคำตอบที่เกี่ยวข้องและน่าสนใจนี้ ) เรียงลำดับการส่งออกของkextstatที่จะทำให้มันง่ายที่จะเห็นซึ่ง kext ใช้หน่วยความจำมากที่สุด (ถึงแม้จะทราบประเภทนี้โดยWiredคอลัมน์ ... มีความคล้ายกันในคาถาที่เรียบง่ายนี้ ตอบด้วยคำอธิบายหากคุณต้องการปรับแต่ง)

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

เดาที่ดี - kextstatและขอขอบคุณเป็นอย่างมากสำหรับการที่มีประโยชน์ออกเรียง อย่างไรก็ตามมันก็ดูเหมือนจะไม่เป็นเช่นนั้นจริง ๆ แล้วเกิดขึ้น: ในระหว่างการดูตัวอย่าง - การกลืน, รอยเท้าหน่วยความจำของcom.apple.nvidia.driver.*ไม่เปลี่ยนแปลง ฉันได้แก้ไขคำถามเพื่อสะท้อนสิ่งนี้
Landak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.