2010-01-13 18 views
1

我開發可可程序,使用的內存可能的最小量的希望。要檢查這一點,我一直在使用活動監視器。我的程序有NSString相當大NSMutableArray含有的情況下,當我鬆開陣列,我沒有得到我所有的記憶回來了。以下示例演示了我的問題。Objective-C的內存不被釋放,大型排列

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:10]; 

    NSLog(@"The array has no elements!"); // Activity monitor says 1.5 megs 
    [NSThread sleepForTimeInterval:10]; 

    NSUInteger i; 
    for(i = 0;i < 1000000;i++) 
    { 
     NSString *str = [[NSString alloc] initWithFormat:@"Number=%d, again it is: %d, one more time for added length: %d", i, i, i]; 
     [array addObject:str]; 
     [str release]; 
    } 

    NSLog(@"We have used lots of memory!"); // Activity Monitor says 108 megs 
    [NSThread sleepForTimeInterval:5]; 

    [array release]; 
    NSLog(@"We have released the array!"); // Activity Monitor says 19 megs 
    [NSThread sleepForTimeInterval:5]; 

    [pool drain]; 
    NSLog(@"We have drained the pool!"); // Activity Monitor still says 19 megs 
    [NSThread sleepForTimeInterval:5]; 

    return 0; 
} 

我加入sleepForTimeInterval電話,所以我可以看到和注意到活動監視器中列出的內存使用情況。在每次停頓時,我都列出了我應該使用的內存量。我幾乎可以肯定,我的問題源於保留/釋放公約中的誤解。有沒有人看到我要去哪裏錯了?

+0

AM柱你在看什麼? – ergosys 2010-01-13 23:24:34

+0

我正在查看Real Memory列。 – 2010-01-14 00:12:58

回答

4

你的代碼是正確的。

我建議使用儀器檢查你的對象分配。您應該看到,釋放數組時,所有內容都已釋放。

你在活動監視器中看到的數字可能會由基金會進行一些NSString的內存緩存的結果,也可能僅僅是操作系統的內存管理器的功能正在處理您的應用程序。

+0

緩存是有道理的。有沒有辦法禁用它,也許有優化設置?一個自定義子類可能會修復這個問題嗎? – 2010-01-14 01:43:41

+0

看了一會兒之後,事實證明它實際上是活動監視器。我使用char **和malloc重寫了相同的代碼,並且存在同樣的問題。活動監視器不提供對已用內存的精確度量。 – 2010-01-14 02:40:00

+0

活動監視器提供應用程序對內存使用的準確度量,但不是衡量分配的度量。爲此,請使用Object Alloc。關於內存緩存的猜測是完全錯誤的;沒有這樣的字符串緩存(但這是一個很好的猜測)。 – bbum 2010-01-14 02:45:26

1

蕩,我只是寫了一個整體的答案缺少你[str release]電話:)

無論如何,你實際上並沒有使用自動釋放池,因爲你是手動allocing一切自己。如果改用[NSString stringWithFormat...]然後釋放繩線,那麼你將要使用的自動釋放池。

-1

內存被清理運行環路之間。

[NSThread sleepForTimeInterval:n] 

阻塞線程,並且不會發生運行循環處理。

http://developer.apple.com/mac/library/documentation/cocoa/reference/Foundation/Classes/NSThread_Class/Reference/Reference.html#jumpTo_12

你不明確釋放內存,你只是遞減保留計數爲0,這將允許運行時在運行循環的下一次迭代清理內存。

「已經在這段時間被自動釋放的對象將在運行循環週期結束時被銷燬......」

http://parmanoir.com/When_does_autorelease_release_%3F

+0

沒有運行循環。這只是一個main()函數,他正在手動管理他的autorelease池。 – Darren 2010-01-13 23:29:23