我一直在毆打我的頭靠在牆上試圖弄清楚我是如何在垃圾收集的可可應用程序中發生內存泄漏的。 (活動監視器中的內存使用量將會增長並增長,使用GC Monitor儀器運行應用程序也會顯示不斷增長的圖形。)Cocoa垃圾收集泄漏內存
我最終將其縮小爲我的代碼中的單個模式。數據被加載到一個NSData中,然後被一個C庫解析(數據的字節和長度傳遞給它)。 C庫具有回調函數,可以觸發並返回子字符串的起始指針和長度(以避免內部複製)。然而,爲了我的目的,我需要將它們轉換成NSStrings並保持一段時間。我通過使用NSString的initWithBytes:length:encoding:方法來做到這一點。我認爲會複製字節,並且NSString會適當地管理它,但有些事情出錯了,因爲這個漏洞像瘋了似的。
這段代碼將「泄漏」或以某種方式欺騙垃圾收集器:
- (void)meh
{
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"holmes" ofType:@"txt"]];
const int substrLength = 80;
for (const char *substr = [data bytes]; substr-(const char *)[data bytes] < [data length]; substr += substrLength) {
NSString *cocoaString = [[NSString alloc] initWithBytes:substr length:substrLength encoding:NSUTF8StringEncoding];
[cocoaString length];
}
}
我可以用活動監視器把這個計時器,只是看內存的使用上去了,以及與GC監測儀器。 (holmes.txt是594KB)
這不是世界上最好的代碼,但它顯示了問題。 (我正在運行10.6,該項目的目標是10.5 - 如果這很重要)。我閱讀了垃圾收集文檔,發現了一些可能的陷阱,但我不認爲我在這裏違反規則做任何事情。不過,不要傷害。謝謝!
這裏只是種植和生長所述對象圖的圖:
當我運行它時,我無法看到任何泄漏,它在運行幾分鐘後徘徊在7.5MB和9MB的內存使用量之間。 – 2010-01-19 17:37:47
這很奇怪。我在10.6.2。我建立在調試和發佈。在所有情況下,我都看到了不斷增長的記憶。 wtf ... – Sean 2010-01-19 17:45:04
我現在已經有其他人在10.5上運行它了,並且他報告說它對他來說似乎也沒有增長。我需要讓10.6+以上的其他人試用。 – Sean 2010-01-19 18:02:09