Cảnh báo bộ nhớ hệ điều hành iPhone. Các cấp độ khác nhau có nghĩa là gì?


85

Về nghệ thuật quản lý bộ nhớ trên các thiết bị iPhone OS: các mức cảnh báo bộ nhớ khác nhau có ý nghĩa gì. Cấp độ 1? Cấp độ 2? Mặt số có chuyển sang 11 không?

Bối cảnh: Sau một thời gian kiểm tra căng thẳng về bộ nhớ - bao gồm chạy ứng dụng iPad của tôi với ứng dụng máy nghe nhạc iPod đang phát, tôi có xu hướng bỏ qua các cảnh báo bộ nhớ ngẫu nhiên nhưng không thường xuyên mà tôi nhận được. Ứng dụng của tôi không bao giờ bị lỗi. Không bao giờ. Ứng dụng của tôi không bị rò rỉ. Và, tốt, các cảnh báo của mems dường như không quan trọng.

Cảm ơn,
Doug

Câu trả lời:


98

Về cơ bản, các cảnh báo có nghĩa là thiết bị sắp hết bộ nhớ và rằng, "Nếu bạn có thể, hãy giải phóng một số bộ nhớ mà bạn không tích cực sử dụng sẽ bị phình ra! ". Nếu việc quản lý bộ nhớ của bạn không chặt chẽ và bạn không có đối tượng nào thực sự có thể bị loại bỏ, chỉ cần chuyển thông báo và bỏ qua nó.


25
LOL "Nếu bạn có thể, vui lòng giải phóng một số bộ nhớ mà bạn không tích cực sử dụng sẽ bị phình ra!" Vô giá ;-) Chúc mừng
dugla

15
Bạn giống như một cựu chiến binh khó chịu trong vũ điệu bộ nhớ wack-a-nốt ruồi của hệ điều hành iPhone.
dugla

193

Cảnh báo mức bộ nhớ được ghi lại bằng SpringBoard. Là một nhà phát triển ứng dụng, bạn không cần quan tâm đến nó. Chỉ cần đáp ứng -{application}didReceiveMemoryWarninglà đủ.


Có 4 mức cảnh báo (0 đến 3). Chúng được đặt từ trình theo dõi bộ nhớ hạt nhân và có thể được lấy bằng hàm not-so-publicOSMemoryNotificationCurrentLevel() .

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

Cách các mức được kích hoạt không được ghi lại. SpringBoard được cấu hình để thực hiện những việc sau trong mỗi cấp bộ nhớ:

  1. Cảnh báo (không bình thường) - Khởi chạy lại hoặc trì hoãn tự động khởi chạy lại các ứng dụng nền không cần thiết, ví dụ như Thư.
  2. Khẩn cấp - Thoát tất cả các ứng dụng nền, ví dụ như Safari và iPod.
  3. Quan trọng và hơn thế nữa - Kernel sẽ tiếp quản, có thể giết chết SpringBoard hoặc thậm chí khởi động lại.

Việc giết ứng dụng đang hoạt động (jetsam) không được SpringBoard xử lý, nhưng launchd.


Cám ơn vì cái này. Đó là một cuộc đấu trí giữa bạn và diễn viên hài Williham về câu hỏi này. Hài hước chiến thắng. Chúc mừng.
dugla

Xin chào, tôi có cùng một vấn đề. Sau khi chạy ứng dụng liên tục hơn 5 lần, tôi nhận được cảnh báo bộ nhớ Đã nhận. Mức = 1 trong 20 lần, nhưng ứng dụng không bị lỗi. Nhưng khi tôi nhận được thông báo này, Đã nhận cảnh báo bộ nhớ. Mức = 2 ứng dụng của tôi bị lỗi. Cấp độ 2 xuất hiện sau khi Cấp độ 1 xuất hiện gần 20 lần. Làm cách nào để ứng dụng của tôi không bị lỗi. Cảm ơn bạn
rongali Srikanth

1
@Kenny: Bộ nhớ ít hơn nghĩa là chúng ta có thể sử dụng tối đa bao nhiêu. Chúng ta có thể có bao nhiêu byte sống. Trong nhật ký sự cố của tôi, tôi có cái này. Trang miễn phí: 371 Trang có dây: 12192 Trang có thể xóa: 0 Quy trình lớn nhất: DTMobileIS Điều này có nghĩa là gì? Tôi nên chăm sóc ở đâu? Cảm ơn bạn.
srikanth rongali

9
@srik: Bạn nên hỏi một câu hỏi mới .
kennytm

@kennytm: cái này vẫn được với ios8? Tôi đã thấy rằng hàm được định nghĩa trong libsystem_c.dylib. Sẽ thật tuyệt nếu tôi có thể tiếp tục và sử dụng nó. Cảm ơn
focs

12

Từ OSMemoryNotification.h ,

/*
** Threshold values for notifications
*/

typedef enum {
    OSMemoryNotificationLevelAny      = -1,
    OSMemoryNotificationLevelNormal   =  0,
    OSMemoryNotificationLevelWarning  =  1,
    OSMemoryNotificationLevelUrgent   =  2,
    OSMemoryNotificationLevelCritical =  3
} OSMemoryNotificationLevel;

totoal 5 mức cảnh báo bộ nhớ (-1,3).

Về mô tả cảnh báo Mức bộ nhớ, câu trả lời của @ KennyTM là tuyệt vời.

Tôi muốn thêm một số điểm liên quan có thể giúp ích cho PM và những người khác.


Bạn nên làm gì khi có Cảnh báo mức bộ nhớ?

Khi nhận được bất kỳ cảnh báo nào trong số này, phương thức xử lý của bạn sẽ phản hồi bằng cách giải phóng ngay lập tức mọi bộ nhớ không cần thiết. Ví dụ: hành vi mặc định của lớp UIViewController là xóa chế độ xem của nó nếu chế độ xem đó hiện không hiển thị; các lớp con có thể bổ sung hành vi mặc định bằng cách xóa các cấu trúc dữ liệu bổ sung. Một ứng dụng duy trì bộ nhớ cache hình ảnh có thể phản hồi bằng cách phát hành bất kỳ hình ảnh nào hiện không có trên màn hình.


Làm thế nào để quan sát cảnh báo Mức bộ nhớ?

Từ http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html

Khi hệ thống gửi cảnh báo bộ nhớ thấp đến ứng dụng của bạn, hãy phản hồi ngay lập tức. iOS thông báo cho tất cả các ứng dụng đang chạy bất cứ khi nào dung lượng bộ nhớ trống xuống dưới ngưỡng an toàn. (Nó không thông báo cho các ứng dụng bị tạm ngừng.) Nếu ứng dụng của bạn nhận được cảnh báo này, ứng dụng phải giải phóng nhiều bộ nhớ nhất có thể. Cách tốt nhất để làm điều này là xóa các tham chiếu mạnh đến bộ nhớ đệm, đối tượng hình ảnh và các đối tượng dữ liệu khác có thể được tạo lại sau này.

UIKit cung cấp một số cách để nhận cảnh báo bộ nhớ thấp, bao gồm những cách sau:

  • Triển khai phương thức applicationDidReceiveMemoryWarning: của đại biểu ứng dụng của bạn.
  • Ghi đè phương thức didReceiveMemoryWarning trong lớp con UIViewController tùy chỉnh của bạn.
  • Đăng ký để nhận UIApplicationDidReceiveMemoryWarningNotificationnotification.

Làm thế nào để giảm dấu chân bộ nhớ ứng dụng của bạn?

  • Loại bỏ rò rỉ bộ nhớ.
  • Tạo các tệp tài nguyên càng nhỏ càng tốt.
  • Sử dụng Dữ liệu cốt lõi hoặc SQLite cho các tập dữ liệu lớn.
  • Tải tài nguyên một cách lười biếng.
  • Xây dựng chương trình của bạn bằng cách sử dụng tùy chọn Thumb.

Thông tin chi tiết tại http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html


Làm thế nào để phân bổ bộ nhớ một cách khôn ngoan?

  • Giảm thiểu việc sử dụng các đối tượng được phát hành tự động: Với tính năng đếm tham chiếu tự động (ARC), tốt hơn là bạn nên cấp phát / init các đối tượng và để trình biên dịch phát hành chúng cho bạn vào thời điểm thích hợp. Điều này đúng ngay cả đối với các đối tượng tạm thời mà trước đây bạn có thể đã tự động cài đặt để ngăn chúng vượt qua phạm vi của phương thức hiện tại.
  • Áp đặt giới hạn kích thước cho tài nguyên : Tránh tải tệp tài nguyên lớn khi tệp tài nguyên nhỏ hơn sẽ làm được. Thay vì sử dụng hình ảnh có độ phân giải cao, hãy sử dụng hình ảnh có kích thước phù hợp cho các thiết bị chạy iOS. Nếu bạn phải sử dụng các tệp tài nguyên lớn, hãy tìm cách chỉ tải phần tệp bạn cần vào bất kỳ thời điểm nào. Ví dụ: thay vì tải toàn bộ tệp vào bộ nhớ, hãy sử dụng các chức năng mmap và munmap để ánh xạ các phần của tệp vào và ra khỏi bộ nhớ. Để biết thêm thông tin về ánh xạ tệp vào bộ nhớ.
  • Tránh các nhóm vấn đề không bị ràng buộc : Các nhóm vấn đề không bị ràng buộc có thể yêu cầu một lượng lớn dữ liệu tùy ý để tính toán. Nếu bộ yêu cầu nhiều bộ nhớ hơn khả dụng, ứng dụng của bạn có thể không thể hoàn thành các phép tính. Ứng dụng của bạn nên tránh những bộ như vậy bất cứ khi nào có thể và khắc phục sự cố với giới hạn bộ nhớ đã biết.
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.