2010-05-26 34 views
84

關於在iPhone OS設備上管理內存的黑色藝術:不同級別的內存警告意味着什麼。 1級? 2級?錶盤是否轉到11?iPhone操作系統內存警告。不同層次意味着什麼?

背景:經過廣泛的內存壓力測試期間 - 包括運行我的iPod音樂播放器應用程序播放iPad應用程序,我傾向於忽略隨機還罕見的內存警告我收到了。我的應用程序從來沒有崩潰。永遠。我的應用程序是無泄漏的。而且,嗯,警告似乎並不重要。

感謝,
道格

回答

95

基本上警告意味着設備運行內存不足,而且,「如果你能請釋放你不積極使用將會是一些內存膨脹!「。如果你的內存管理很緊張,而且你沒有任何實際上可以丟棄的對象,只需傳遞消息並忽略它。

+25

大聲笑「如果你可以請釋放一些你不會積極使用的內存!」無價的;-) 乾杯 – dugla 2010-05-26 19:11:20

+15

你聽起來像iPhone OS怪胎記憶舞蹈的磨損老兵。 – dugla 2010-05-26 19:15:00

+1

來自_The麥田守望者在Rye_? '偉大的代碼;)' – wagashi 2011-09-28 11:18:12

192

SpringBoard記錄內存級警告。作爲一名應用程序開發人員,您無需關心它。只需要回覆-{application}didReceiveMemoryWarning就足夠了。


有4級警告(0到3)。這些是從內核內存觀察器設置的,可以通過not-so-public function OSMemoryNotificationCurrentLevel()獲得。

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

如何觸發級別沒有記錄。 SpringBoard被配置爲在每個內存級別執行以下操作:

  1. 警告(非正常) - 重新啓動或延遲不必要的後臺應用程序的自動重新啓動例如,郵件。
  2. 緊急 - 退出所有後臺應用程序,例如Safari和iPod。
  3. 關鍵和超越 - 內核將接管,可能殺死SpringBoard甚至重新啓動。

殺死活動應用程序(jetsam)不是由SpringBoard處理,而是由launchd處理。

+0

謝謝你。這是你和這個問題喜劇演員Williham之間的折騰。幽默勝利。乾杯。 – dugla 2010-05-26 19:12:53

+0

嗨, 我有同樣的問題。連續運行5次以上的應用程序後,我收到內存警告。 Level = 1 20次,但應用程序沒有崩潰。 但是,當我收到此消息時,收到內存警告。 Level = 2我的應用程序崩潰。 Level2出現在Level1出現近20次之後。我如何讓我的應用程序不會崩潰。 謝謝 – 2010-06-22 13:53:42

+3

@srik:使用較少的內存。 – kennytm 2010-06-22 14:24:02

12

OSMemoryNotification.h

/* 
** Threshold values for notifications 
*/ 

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

totoal 5個級別的存儲器警告(-1,3)。

關於內存級別的警告說明,@ KennyTM的答案是優秀的。

我想補充一些相關的點,這可以幫助PM等。


有內存級別警告時應該怎麼做?

一旦收到任何這些警告,你的處理方法應該立即釋放所有不需要的內存響應。例如,如果該視圖當前不可見,則UIViewController類的默認行爲是清除其視圖;子類可以通過清除額外的數據結構來補充缺省行爲。維護圖像緩存的應用可能會通過釋放當前不在屏幕上的任何圖像進行響應。


如何觀察內存級別警告?

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

當系統調度低內存警告到您的應用程序,立即迴應。當可用內存量低於安全閾值時,iOS會通知所有正在運行的應用程序。 (它不通知掛起的應用程序。)如果您的應用程序收到此警告,它必須釋放盡可能多的內存。這樣做的最好方法是刪除對高速緩存,映像對象和其他可以稍後重新創建的數據對象的強引用。

UIKit中提供了幾種方式來接收低內存警告,其中包括:

  • 落實applicationDidReceiveMemoryWarning:您的應用程序 委託的方法。
  • 覆蓋您的自定義 UIViewController子類中的didReceiveMemoryWarning方法。
  • 註冊以接收 UIApplicationDidReceiveMemoryWarningNotificationnotification。

如何減少你的應用程序的內存佔用?

  • 消除內存泄漏。
  • 使資源文件儘可能小。
  • 對大數據集使用Core Data或SQLite。
  • 懶洋洋地加載資源。
  • 使用Thumb選項構建您的程序。

詳細的http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/PerformanceTuning/PerformanceTuning.html


如何明智地分配內存?

  • 減少你的自動釋放對象的使用:具有自動參考 計數(ARC),這是更好地分配/初始化對象,讓 編譯器釋放他們爲你在適當的時候。 即使對於過去可能有 自動釋放的臨時對象也是如此,以防止它們超出當前方法的範圍。
  • 對資源施加大小限制:避免在較小的資源文件中加載大型資源文件 。 不是使用高分辨率圖像,而是使用適合iOS設備的尺寸。如果您的 必須使用大型資源文件,請在任何給定時間找到只加載您需要的文件部分的方法。例如,而不是 將整個文件加載到內存中,請使用mmap和munmap函數 將文件的部分映射到內存和從內存中映射出來。有關將文件映射到內存的更多信息 。
  • 避免無限問題集:無界問題集可能需要 來計算任意大量的數據。如果該設置需要更多的內存,則可能是您的應用程序無法完成 的計算。您的應用程序應儘可能避免使用此類設置,並且 可處理已知內存限制的問題。
+1

我喜歡上一個要點,「製作一個不同的程序」。 – Brent 2013-07-02 00:15:09