2010-07-29 155 views
1

我正在編寫一個應用程序(基本上是它的又一個iBooks克隆),它消耗了大量內存。根據輸入數據的不同,內存佔用空間可能會高達70-80 MB(如MemoryMonitor狀態)或甚至更高。
它在一段時間內工作正常,但隨着時間的推移它往往會增加其內存佔用。
因此,讓我們說你打開一本書,應用程序的內存佔用從6MB增加到60MB。那麼應該發生的是,關閉本書並將內存佔用降低到6MB。而事實並非如此。它降低到〜30MB(根據MemoryMonitor),這導致了幾次迭代中的崩潰。無法找到內存泄漏的源

現在有趣的部分。我試過鐺靜態分析器,但它沒有顯示任何問題(除了指出單身等)。
我試過使用泄漏工具,但他們表明我只有2-3KB的總數(應該是〜24MB +)。而且,我並不擔心這些樂器實際上是在告訴我真相。我已經仔細檢查了所有儀器報告的泄漏情況,我99%確定那裏沒有泄漏。
我試過使用分配工具,但它顯示在關閉本書之後,內存佔用降到6MB,這是所需的數字。但這並沒有什麼意義,因爲如果是這樣的話,應用程序就不會崩潰。 我也嘗試使用資源字節圖的openglES分析器,但它也顯示沒有泄漏或任何其他可疑。
我曾經信任的唯一工具是內存監視器,因爲當它顯示〜110MB真實內存時,我的應用程序總是會崩潰。但是,a)它沒有顯示分配內存的情況,b)當我嘗試使用相同的應用程序構建多次運行它時,發現它的讀數差異顯着,從運行到運行(15-20MB差異,相同)。

所以所有的儀器都告訴我,我的代碼是好的(除了內存監視器,這似乎是正確的,但沒有用於任何測量),但它不斷粉碎。
我不知道接下來應該做什麼。我當然不能減少整體內存佔用,我找不到內存泄漏(這仍然是我想要的方式)。

所以這是我的問題:
1)除了上面提到的那些之外,有沒有找到泄漏的方法? iPhone的另一個profiler程序也許?
2)我已經讀過關於某種碎片整理問題,例如當你分配/重新分配許多對象,然後應用程序不會將釋放的塊返回給操作系統,這可能會導致無法分配大塊內存它太支離破碎,操作系統不會給你更多的內存。我從來沒有見過一個好的話題。如果任何人都可以將鏈接留給相關主題,那將會很棒。
3)我試過禁用程序的幾個部分,到目前爲止看起來整個問題可能來自使用CoreText框架。我想聽聽任何曾經使用過這個框架的人,並且可以確認/否認那裏存在任何問題。
4) - 其他建議 -

P.S.我沒有包含任何代碼片斷,因爲代碼本身非常龐大,我無法將可疑代碼的數量減少到合理的數量。

回答

2

也許有點傻,但是當發生了大致類似的事情時,我意識到我已啓用NSZombies 。從那以後,我的didFinishLaunching:在頂部有幾條線:

if (getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled")) { 
    NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!"); 
} else { 
    NSLog(@"No NSZombieEnabled or NSAutoreleaseFreedObjectCheckEnabled"); 
} 
+0

詛咒的殭屍!就是這樣! 我花了多少時間試圖找出問題的根源。 我也很驚訝,內存分配/泄漏工具忽略了整個殭屍。 – Alexey 2010-07-30 07:19:30

+0

他們沒有 - 他們把他們關閉,這就是爲什麼他們報告這麼少。這在你的文本中對我來說是最大的暗示。 – Kalle 2010-07-30 08:03:26

+0

我不確定儀器是否將其關閉。在我手動禁用它們之後,內存監視器開始報告完全不同的數字,而來自泄漏/分配儀器的讀數仍然相同(我正在運行帶有分配+泄漏+操作系統+內存監視器的儀器)。 這就是爲什麼我認爲他們忽略他們而不是關閉他們。 – Alexey 2010-07-30 09:06:07

0

問題是,泄漏只發現仍然保留的內存,您沒有引用。

在你的情況下,你仍然有保留的內存,你也有參考。就泄漏而言,它不能說明你是否打算保留這種記憶,所以它什麼也沒說。

在你的情況下,最好的辦法是使用對象Alloc工具 - 記錄一個會話,然後對於一個成長記憶的區域alt-選擇區域,並選擇「保留和仍然存在」選項側。現在通過所報告的對象並找出不應該保留的內容 - 一個好的起點是尋找仍然保留的任何自己的類並找出你認爲被釋放的內容。

較新的XCode也有一個工具,它結合了泄漏和對象分配,我不能再多說什麼,因爲它是在NDA下 - 但你可能想嘗試一下。我不知道是否必須將它安裝在單獨的系統上才能訪問改進的工具,雖然...