2010-02-26 51 views
2

我正在運行一些內存分析爲我的應用程序在SDK 3.2中,我用'泄漏'探查器找到我所有的內存泄漏,我把它們全部插上。這是一個scrollView導航控制器應用程序,其中有瓷磚,並且您可以單擊一個瓷磚,然後轉到新的瓷磚視圖等等,我可以深入多層並回到頂部,並且「泄漏」分析器說明所有事物很酷。但是,如果我在'ObjectAlloc'分析器中觀察內存佔用情況,內存佔用會隨着我越來越深(這看起來合理)而變得越來越高,但是當我退出視圖時,內存佔用不會減少正如我所料。內存泄漏工具告訴我零泄漏,但內存佔用不斷上升

我知道這是應用程序的模糊描述,但我不能準確地發佈數百行代碼:)此外,應該指出的是,我使用coreData來存儲圖像數據,因爲數據庫正在增長在選擇更多節點時的大小,不知道是否/何時從內存釋放。

什麼給?

回答

1

核心的數據存儲管理的信息是良好的信息和技術上的答案通過亞瑟Kalliokoski是一個很好的答案:韭菜和對象分配之間的區別。我在這裏遇到的一個特殊問題與模擬器中一個按鈕上的setBackgroundImage顯然已知的錯誤有關,它會產生內存「泄漏」,因爲它不會釋放釋放UIImage的內存。

3

根據你在覈心數據中構建的對象圖的方式,它的內存使用可能會意外增長。

一個常見的錯誤是將對象存儲在一個複雜且經常出現故障(加載到內存中)的實體中。這導致在實體的任何其他部分被引用時,大塊被加載/保留在內存中。隨着對象圖形的增長,它會消耗越來越多的內存,除非您主動刪除對象並保存圖形。

例如:您的個人實體包含大量文本信息,例如名稱,地址等以及一張大照片。如果您將照片設置爲個人實體的屬性,則只要個人實體出現故障,它就會記憶在內存中。如果您獲得屬性名稱,那麼photo屬性也在內存中。

爲了避免這種情況,blob應該在自己的實體中,然後鏈接到關係中的其他實體。由於關係對象在被直接調用之前不會發生故障,所以直到需要時它們纔會保持內存不足。

+0

我在我的對象圖中做了這一點,所有圖像都有自己的實體。但是,如果我向coreData添加了大量新項目(包括圖像),由於我剛剛添加了圖像數據,因此圖像數據在內存中,我如何「刪除」某些內容以從內存中刪除實體? – Shizam 2010-02-26 04:38:55

+0

找到'重新斷層'的條目,給它一個去。 – Shizam 2010-02-26 04:53:57

+0

不知道這是否適用於您的應用,如果確實如此,您可能已經覆蓋了該應用,但您只需在全尺寸圖片上加載全尺寸圖片即可。例如。一個tableview將在一個單元格的縮略圖中顯示一個完整大小的圖像。它外表看起來很小但記憶明智,它非常巨大。如果可能的話,您應該創建並存儲縮略圖,這些縮略圖的實際大小隻有足夠的分辨率。然後只將完整圖像加載到需要的地方,然後立即處理它們。 – TechZen 2010-02-26 16:57:07

0

你可以有一個不斷增長的程序,而不必泄漏內存。假設您從輸入中讀取單詞並將它們存儲在鏈接列表中動態分配的內存塊中。當你閱讀更多的單詞時,列表不斷增長,但所有內存仍然可以通過列表訪問,所以沒有內存泄漏。

1

僅僅因爲沒有基於refcount的泄漏,並不意味着你沒有在字典「緩存」中填充某些東西並忘記它;那些不會顯示爲泄漏,因爲它有有效的引用(該字典仍然有效,所有其子的引用也是如此)。你還需要尋找有效但不必要的對象。

最簡單的方法是讓它運行太久,然後按類型對對象計數進行排序,看看誰有一個巨大的數字 - 然後追蹤參考圖(在Obj-C中可能很難)。如果Instruments不直接執行此操作,則可以編寫一個DTrace腳本來執行此操作。

1

重申:

char *str1 = malloc(1000); 
char *str2 = malloc(1000); 
    . 
    . 
    . 
char *str1000 = malloc(1000); 

是不是內存泄漏,但

char *str1 = malloc(1000); 
char *str1 = malloc(1000); //Note! No free(str1) in between! 

內存泄漏

+0

謝謝,我明白這一點。我的問題在於我創建子視圖(並觀察內存增加),然後正確釋放所有視圖(但內存佔用不會減少)。我越想越多,我認爲它與向coreData添加新信息有關。 – Shizam 2010-02-26 04:41:47

4

這聽起來像它可能是幾件事情之一:

  • 內存釋放後不還給操作系統。這是C運行時的通用設計。當您執行分配時,C運行時會爲其使用分配更多內存,並返回一大塊內存供您使用。當你做一個空閒的時候,C運行時只是將它標記爲釋放,但不會將它返回給操作系統。因此,如果泄漏工具正在讀取OS級統計信息而不是C運行時統計信息,那麼泄漏工具將無法報告內存使用情況的相應減少。

  • 泄漏工具內存報告的誤導值。泄漏工具可能會看到與C運行時不同的值,並報告的值會導致您擔心,即使沒有任何錯誤(就像人們試圖在Windows中使用任務管理器來檢測泄漏並因結果混淆一樣)對於這項工作確實是一個非常糟糕的工具)。

  • 碎片化。您的應用程序可能遭受內存碎片。這是當你分配,然後釋放然後分配,後續嘗試分配大於釋放留下的「漏洞」。發生這種情況時,會分割內存空間,留下不可用的空洞,從而阻止大量連續的內存塊,並強制使用越來越多的內存空間,直到內存不足。這是一種病理狀況,修復通常是特定於應用程序的。

我認爲這三個建議中的第一個很可能是發生了什麼事情。