5

我現在正在使用的應用程序隨着時間的流逝積累越來越多的內存。這不是真正的內存泄漏,因爲泄漏工具不會將其識別爲泄漏,但它會持續佔用越來越多的內存。當「內存泄漏」是由Foundation框架引起時該怎麼辦?

我一直在使用儀器(內存分配工具)來找出爲什麼發生這種情況,我現在正在製作堆積照片以便找出運行週期中不同點之間的內存差異。看起來在每個週期之後,使用的內存增加了大約560 KB。

這是怎麼看起來像在儀器工具:

Instruments initial

並選擇CFString字符串行時:

CFString allocation

完整的堆棧跟蹤從右側的樣子這個:

0 CoreFoundation _CFRuntimeCreateInstance 
    1 CoreFoundation __CFStringCreateImmutableFunnel3 
    2 CoreFoundation CFStringCreateWithBytes 
    3 Foundation -[NSString initWithCoder:] 
    4 Foundation _decodeObject_old 
    5 SyncServices -[ISDProperty initWithCoder:] 
    6 SyncServices -[ISDRelationship initWithCoder:] 
    7 Foundation _decodeObject_old 
    8 Foundation _decodeValueOfObjCType 
    9 Foundation -[NSUnarchiver decodeValueOfObjCType:at:] 
    10 Foundation -[NSArray(NSArray) initWithCoder:] 
    11 Foundation _decodeObject_old 
    12 SyncServices -[ISDEntity initWithCoder:] 
    13 Foundation _decodeObject_old 
    14 Foundation _decodeValueOfObjCType 
    15 Foundation -[NSUnarchiver decodeValueOfObjCType:at:] 
    16 Foundation -[NSArray(NSArray) initWithCoder:] 
    17 Foundation _decodeObject_old 
    18 SyncServices -[ISDRelationship initWithCoder:] 
    19 Foundation _decodeObject_old 
    20 Foundation _decodeValueOfObjCType 
    21 Foundation -[NSUnarchiver decodeValueOfObjCType:at:] 
    22 Foundation -[NSArray(NSArray) initWithCoder:] 
    23 Foundation _decodeObject_old 
    24 SyncServices -[ISDEntity initWithCoder:] 
    25 Foundation _decodeObject_old 
    26 Foundation _decodeValueOfObjCType 
    27 Foundation -[NSUnarchiver decodeValueOfObjCType:at:] 
    28 Foundation -[NSArray(NSArray) initWithCoder:] 
    29 Foundation _decodeObject_old 
    30 SyncServices -[ISDRelationship initWithCoder:] 
    31 Foundation _decodeObject_old 
    32 Foundation _decodeValueOfObjCType 
    33 Foundation -[NSUnarchiver decodeValueOfObjCType:at:] 
    34 Foundation -[NSArray(NSArray) initWithCoder:] 
    35 Foundation _decodeObject_old 
    36 SyncServices -[ISDEntity initWithCoder:] 
    37 Foundation _decodeObject_old 
    38 Foundation _decodeValueOfObjCType 
    39 Foundation -[NSUnarchiver decodeValueOfObjCType:at:] 
    40 Foundation -[NSArray(NSArray) initWithCoder:] 
    41 Foundation _decodeObject_old 
    42 SyncServices -[ISDRelationship initWithCoder:] 
    43 Foundation _decodeObject_old 
    44 Foundation _decodeValueOfObjCType 
    45 Foundation -[NSUnarchiver decodeValueOfObjCType:at:] 
    46 Foundation -[NSArray(NSArray) initWithCoder:] 
    47 Foundation _decodeObject_old 
    48 SyncServices -[ISDEntity initWithCoder:] 
    49 Foundation _decodeObject_old 
    50 Foundation +[NSUnarchiver unarchiveObjectWithData:] 
    51 SyncServices -[ISDObjectGraphWrapper initWithCoder:] 
    52 Foundation -[NSKeyedPortCoder decodeObjectForKey:] 
    53 Foundation -[NSArray(NSArray) initWithCoder:] 
    54 Foundation -[NSKeyedPortCoder decodeObjectForKey:] 
    55 Foundation -[NSKeyedPortCoder _decodeObjectNoKey] 
    56 Foundation -[NSKeyedPortCoder _walkAndDecodeDataWithType:at:chase:invocation:inStructure:] 
    57 Foundation decodeInvocationArguments 
    58 Foundation -[NSKeyedPortCoder decodeInvocation] 
    59 Foundation -[NSKeyedPortCoder decodeObjectForKey:] 
    60 Foundation -[NSConnection handleRequest:sequence:] 
    61 Foundation -[NSConnection handlePortCoder:] 
    62 Foundation -[NSConnection dispatchWithComponents:] 
    63 Foundation __NSFireMachPort 
    64 CoreFoundation __CFMachPortPerform 
    65 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ 
    66 CoreFoundation __CFRunLoopDoSource1 
    67 CoreFoundation __CFRunLoopRun 
    68 CoreFoundation CFRunLoopRunSpecific 
    69 Foundation -[NSRunLoop(NSRunLoop) runMode:beforeDate:] 
    70 SyncServices -[ISyncConcreteSession _waitForTransitionFromPhase:untilDate:] 
    71 SyncServices +[ISyncSession _sessionWithClient:entityNames:beforeDate:clientHasTruthForEntityNames:quietlyPushTruth:target:selector:anchors:hasChanges:skip:error:] 
    72 SyncServices +[ISyncSession beginSessionWithClient:entityNames:beforeDate:] 
    73 SyncServices -[ISyncConcreteSessionDriver _beginSyncSession:] 
    74 SyncServices -[ISyncConcreteSessionDriver _preSync] 
    75 SyncServices -[ISyncConcreteSessionDriver _sync:] 
    76 SyncServices -[ISyncConcreteSessionDriver sync] 
    77 **Our application** - [SLSyncOperation performLocalSync] /Users/andrei/Desktop/MacOSX_Client/osx/Classes/SLSyncOperation.m:94 
    78 **Our application** -[SLSyncOperation main] /Users/andrei/Desktop/MacOSX_Client/osx/Classes/SLSyncOperation.m:251 
    79 Foundation -[__NSOperationInternal start] 
    80 Foundation ____NSOQSchedule_block_invoke_2 
    81 libdispatch.dylib _dispatch_call_block_and_release 
    82 libdispatch.dylib _dispatch_worker_thread2 
    83 libsystem_c.dylib _pthread_wqthread 
    84 libsystem_c.dylib start_wqthread 

我正在使用SyncServices以獲取聯繫信息。我正在使用一個ISyncSessionDriver以一定的時間間隔(10秒,可以在內存分配圖像上看到)檢查(同步)新信息。代碼看起來像這樣。

SLSyncSessionDriverDataSource *dataSource = [[SLSyncSessionDriverDataSource alloc] initWithManagedObjectModel:managedObjectModel context:managedObjectContext]; 

ISyncSessionDriver *localDriver = [ISyncSessionDriver sessionDriverWithDataSource:dataSource]; 
SLSyncSessionDriverDelegate *theDelegate = [[SLSyncSessionDriverDelegate alloc] init]; 
[localDriver setDelegate:theDelegate]; 

[theDelegate release]; 
[dataSource release];  

[localDriver sync]; 

感謝您給我的任何幫助!

回答

2

假設你發現了一個真正的泄漏,一些想法:

  • 時,有可能成爲新的 信息只能運行同步(觀看與kqueue的或FSEvents在~/Library/Application Support/AddressBook變化)。

  • 您可以在定期循環使用的子進程中運行同步,或者使用先前的建議,只需一次運行該進程即可執行同步,然後退出。

同步服務從來沒有工作非常順利,並棄用的10.7,所以我想它不會看到太多,如果任何額外的工作。我不認爲這是一個浪費時間來提出一個獨立的例子和submit it as a bug,特別是如果它泄漏這個不好。此外,我會建議在地址簿框架上提交另一個錯誤,說明您希望能夠檢查/通知新的/更新的信息。

+0

感謝您的回答。 fork(創建一個子進程)在OSX上似乎並不能很好地工作,特別是在使用其他框架的應用程序中。我已經嘗試過FSEvents,並且工作得很好。最終我對代碼有了更好的瞭解,並發現它是一個*實例變量*,導致了這種情況。我會一次又一次地爲它分配內存而不釋放。釋放它後,它工作正常。有趣的是,XCode分析器沒有註冊我正在做的潛在內存泄漏。 – Andrei

+0

很高興你知道了!是的,一旦你做圖形化的東西,你就不能分叉,但是還有其他的方法(例如NSWorkspace或Launch Services是高級的,還有更低級的)來啓動子應用程序。在Lion上,您還可以查看XPC服務。 –