Tại sao bộ nhớ bị rò rỉ xuất hiện được đặt vào kernel_task và tại sao OS X không thể thu gom rác


11

Trước đây tôi đã được thông báo rằng một dấu hiệu cho thấy một số ứng dụng bị rò rỉ bộ nhớ là kernel_taskcó dung lượng bộ nhớ lớn, thường là theo thứ tự gigabyte. Nếu một sự cố kextxảy ra gây ra việc sử dụng bộ nhớ này, chúng ta sẽ thấy sự khác biệt giữa bộ nhớ được phân bổ và những người dự kiến ​​sẽ được phân bổ, tức là

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

sẽ trả lại một cái gì đó ngoài các từ 'Có dây' và 'Tên'.

Trong khi viết luận án của mình, tôi đã nhận thấy rằng việc thay đổi pdf trong khi nó được mở trong Bản xem trước thường gây ra những điều tồi tệ xảy ra: đôi khi, việc sử dụng bộ nhớ kernel_taskcó thể tăng lên khoảng tám gigabyte hoặc hơn. Nếu tôi giết bản xem trước, nó sẽ trở lại bình thường ngay lập tức . Vì vậy, rõ ràng có điều gì đó không ổn - và Preview đang rò rỉ bộ nhớ trong những điều kiện này.

Vì vậy, câu hỏi của tôi là: nếu tôi biết rằng một quy trình đã bị rò rỉ ram thông qua sự gia tăng đột ngột và bất ngờ về dấu chân kernel_task, tại sao OS X không thể biết rằng đã xảy ra sự cố. Nếu giết Preview phục hồi của tôi mất tích malloc()'d bộ nhớ, tại sao không Darwin làm thu gom rác thải automagically cho tôi?

Tôi có hiểu lầm cơ bản về cách quản lý bộ nhớ hoạt động không?

EDIT: (15/9/15)

Đây là một minh chứng về những gì tôi đang nói về. Trước hết, tôi nhận thấy việc sử dụng bộ nhớ cao bằng cách kernel_task(lưu ý Xem trước đang mở, chỉ hiển thị ở dưới cùng của Trình giám sát hoạt động, sử dụng 333 MiB của ram):

Sử dụng bộ nhớ kernel cao

Theo các nhận xét hữu ích của Ashley bên dưới, hãy tìm hiểu xem mỗi kext đang sử dụng bao nhiêu:

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

Vì vậy, không phải là một số tiền lớn. Máy của tôi có cả GPU rời và tích hợp; trình điều khiển của họ chỉ sử dụng một vài MiB ram có dây. Theo linh cảm của tôi, chúng ta hãy giết Preview và xem điều gì xảy ra với dấu chân bộ nhớ của kernel_task:

Giết trước giúp mọi thứ

Xem trước đã biến mất, và dấu chân bộ nhớ của kernel đã giảm đáng kể. Vẫn không có bằng chứng về sự thay đổi trong cách sử dụng kext: đầu ra của lệnh trên không thay đổi.

Chỉnh sửa : Bug báo cáo là số 22701036. Tôi vẫn đang chờ phản hồi từ apple. Không có gì đặc biệt thú vị nếu bạn kiểm tra quy trình trong ActivityMonitor, nhưng có lẽ tôi đang thiếu thứ gì đó.


Tôi bối rối về hai điều - bạn có thể làm rõ? 1) Tôi nghĩ rằng difflệnh của bạn đang so sánh các cột SizeWiredcột từ kextstatđầu ra. Tôi đồng ý rằng đó Sizelà "bộ nhớ được phân bổ", nhưng tôi không nghĩ Wiredlà "dự kiến ​​sẽ được phân bổ" ( man kextstatmô tả nó là "Số byte bộ nhớ có dây của bộ nhớ kernel mà kext chiếm"). 2) Bạn có thấy sự khác biệt giữa SizeWiredkhi bạn gặp sự cố với Xem trước không?
Ashley

1) Bạn nói đúng - Tôi đang so sánh các yếu tố trong Kích thước và Có dây từ kextstat. Hiểu biết của tôi là nếu một kext bị rò rỉ, thì các byte được phân bổ và các byte mà kernel biết được phân bổ sẽ khác nhau. Trong trường hợp này, tôi đã đặt nó ở đó để cho thấy rằng tôi không có một kext bị rò rỉ - vì vậy, 2) điều này không xảy ra khi Preview ăn ram. Thay vào đó, kernel_taskphát triển rất nhiều. Tôi sẽ thử và tạo lại vấn đề này và chụp ảnh :-).
Landak

Cảm ơn! Đợi một chút: Tôi chỉ đang viết một câu trả lời có thể giúp ích.
Ashley

Câu trả lời:


6

Các lõi của OS X không phải là thu gom rác thải; Ikit libkern C ++ Runtime yêu cầu các nhà phát triển quản lý bộ nhớ của riêng họ.

Quản lý bộ nhớ Mac

Từ cách quản lý bộ nhớ hoạt động trong Mac OS X?

Apple ghi lại các cấp độ thấp nhất của Mach Kernel và hệ thống con bộ nhớ ảo khá tốt trên web như một phần của tài liệu dành cho nhà phát triển.

Vì hạt nhân đó được phát triển bởi Đại học Carnegie Mellon , bạn có thể tìm thấy hàng tá bài viết mô tả nó khá dễ dàng.

Những nguồn khác

Thu gom rác thải

Thu gom rác tồn tại ở lớp người dùng hoặc ứng dụng. Ngay cả ở lớp này, bộ sưu tập rác chỉ giúp nếu ứng dụng đã giải phóng tất cả các khiếu nại vào bộ nhớ. Một phụ thuộc tròn có thể đánh bại bộ sưu tập rác. Bộ sưu tập rác tự nó là một lĩnh vực nghiên cứu phát triển và khó có được quyền .

Báo cáo lỗi và rò rỉ bộ nhớ

Lỗi trong OS X sẽ bị rò rỉ bộ nhớ. Với kích thước của cơ sở mã, điều này là gần như chắc chắn.

Vui lòng báo cáo lỗi tái sản xuất trực tiếp cho Apple . Mọi báo cáo lỗi đều có ích và có thể ví dụ của bạn sẽ là ví dụ giúp các kỹ sư của Apple tìm ra nguyên nhân.


Điều này là đáng thất vọng, nhưng chắc chắn là chính xác. Tôi đã báo cáo lỗi cho Apple - Tôi chỉ thấy phiền phức!
Landak

2
Xin vui lòng bạn có thể chia sẻ số lỗi như là một chỉnh sửa cho câu hỏi của bạn. Những người khác thấy câu hỏi của bạn hữu ích sau đó có thể gửi các lỗi trùng lặp lưu ý đến bản gốc của bạn. Một đống lỗi liên quan sẽ giúp chứng minh thêm thời gian kỹ thuật.
Graham Miln

4

Theo suy đoán của tôi, giả sử máy Mac của bạn có GPU tích hợp (ví dụ Intel Iris Graphics).

Khi bạn mở luận án trong Bản xem trước, bộ nhớ card đồ họa được sử dụng để giữ hình ảnh ("kết cấu") của cửa sổ Xem trước và có lẽ một số trang ngoài màn hình nhưng được giải mã từ luận án.

Với một card đồ họa tích hợp, bộ nhớ video thực sự (một phần?) Nằm trong RAM hệ thống, được chia sẻ giữa CPU và GPU. Trên một số card đồ họa tích hợp, dung lượng RAM hệ thống được sử dụng được phân bổ động (xem Apple HT204349 ).

Tôi đoán rằng bạn đang liên tục thấy một lỗi trong trình điều khiển card đồ họa và / hoặc Preview, không giải phóng bộ nhớ hệ thống chính xác khi Preview tải lại luận án PDF của bạn. (Tuy nhiên, lỗi này được giảm nhẹ bởi OS X / trình điều khiển giải phóng bộ nhớ một cách chính xác khi bỏ xem trước.)

Bạn có thể thử nhìn vào đầu ra kextstatvà xem các số trong Sizecột có tăng lên khi bạn gặp sự cố không. Giả thuyết của tôi là việc tăng 8GB mà bạn đề cập sẽ là do trình điều khiển card đồ họa.

Lệnh sau (từ một nhận xét về câu trả lời thú vị và có liên quan này ) sắp xếp đầu ra kextstatđể giúp dễ dàng xem kext nào đang sử dụng nhiều bộ nhớ nhất (mặc dù lưu ý cách sắp xếp này theo Wiredcột ... có một câu thần chú tương tự, đơn giản hơn trong này trả lời với một lời giải thích nếu bạn muốn điều chỉnh này).

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

Dự đoán tốt - và cảm ơn bạn rất nhiều vì một đầu ra được sắp xếp hữu ích kextstat. Tuy nhiên, nó vẫn không giống như những gì đang thực sự xảy ra: trong quá trình ngấu nghiến Xem trước, dấu chân bộ nhớ com.apple.nvidia.driver.*không thay đổi. Tôi đã chỉnh sửa câu hỏi của mình để phản ánh điều này.
Landak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.