2014-11-22 76 views
0

後釋放我有一個使用dispatch_async功能:dispatch_async,內存不被執行

- (IBAction)action:(id)sender { 
    int i=10000; 
    NSString * data; 
    dispatch_queue_t queue = dispatch_queue_create("com.wang.queue", NULL); 
    __weak ViewController* weakSelf = self; 
    while(i>0) 
    { 
     @autoreleasepool { 
      data = [[NSString alloc]initWithFormat:@"%i",i]; 
      NSString * str = data; 
      dispatch_async(queue, ^{{ 
       [weakSelf print:str]; 
      }}); 
      i--; 
     } 
    } 
} 


-(void) print:(NSString*)str 
{ 
    NSLog(@"%@",str); 
    str = nil; 
} 

然後我按連續五次的按鈕。在運行完成後,內存不會減少。所以我用Instrument來分析內存被佔用的地方。 這樣的:

img.bbs.csdn.net/upload/201411/19/1416403576_473540.png

結果表明, 「數據」 的內存被釋放。這是佔用內存的「VM:性能工具數據」。細節是:

img.bbs.csdn.net/upload/201411/19/1416403630_487530.png

我想一想 「dispatch_async」 什麼東西永遠不會被釋放。

誰能告訴我是什麼讓內存這樣執行?感謝!

+0

「self」在保留它的塊中被引用,但該方法也保留該塊,因此形成保留週期。在塊外聲明'__weak MyObjType * weakSelf = self;'並在塊內使用'weakSelf'而不是'self'。 – 2014-11-22 14:24:10

+0

我已經改變了我的代碼,如你所說,像這樣: __weak ViewController * weakSelf = self; 然後[weakSelf print:data]; 但沒有任何改變。 你會在xcode中試用嗎?謝謝! – Allen 2014-11-22 16:34:35

+0

@Achilles這不是一個保留週期(強參考週期)。 – Rob 2014-11-22 16:53:04

回答

1

一對夫婦的想法:

  1. 您使用NSString對象,但也有NSString緩存/優化,可以扭曲這種分析的種種。通常應該謹慎使用NSString對象進行內存分析。您可能需要使用NSObject或某些自定義類重複此操作。我認爲這不是問題,但是在調試內存分配時總是需要注意。

  2. 您正在使用@autoreleasepool但您沒有autorelease對象。我認爲你把這個游泳池做得很謹慎,但是你的主要物品並不是自動釋放的,所以這個游泳池可能不會給你買東西。另外,僅供參考,無論如何,GCD都有自己的autorelease池。

  3. 即使你確實有autorelease對象時,data變量您@autoreleasepool的範圍之外定義,你就永遠不會消除游泳池內的最終很強的參考,所以池不會完成任何事情。您應該儘可能使用盡可能最小的範圍作爲變量。在這種情況下,我只是退休data變量,只需使用您的本地str變量。

  4. 有人建議你可能有一個保留週期(又名a強參考週期)。沒有這樣的循環,至少在目前與我們分享的代碼中沒有。儘管如此,對於我來說,「性能工具數據」似乎與您創建的10,000個對象無關。你有347個對象,佔180 MB。

    我想知道這個「性能數據」是Instruments本身正在創建的東西(例如快照,堆棧跟蹤等)。我已經做了一些實驗,並且無法重現您描述的行爲。我試圖改變Xcode方案來打開一堆日誌記錄選項(例如殭屍,內存檢查,日誌記錄等),我嘗試更改儀器以記錄最大量的信息(例如頻繁快照等,保持丟棄項目,記錄參考計數等)。所有這些都無濟於事。

    也許你可以分享你可能打開的儀器設置(或嘗試關閉幾個)。同樣的方案爲您的應用程序(確保您已關閉不必要的日誌記錄)。另外,請編輯您的問題,向我們提供有關您正在使用的Xcode/Instruments的版本以及目標操作系統版本等的詳細信息。

+0

我使用Xcode6.1和OS 10.10,而且我從不改變Instrument.For的第1點,如您所說,我使用其他NSObjet,但沒有任何改變。對於第3點,我使用了本地值「str」,但是記憶按照beford表示。 @搶 – Allen 2014-11-24 04:40:59