Что делать, если "утечки памяти" вызваны платформой Foundation? - PullRequest
5 голосов
/ 24 августа 2011

Приложение, над которым я сейчас работаю, со временем накапливает все больше и больше памяти.На самом деле это не утечка памяти, поскольку инструмент «Утечки» не распознает ее как утечку, но это то, что требует все больше и больше памяти.

Я использую инструменты (инструмент выделения памяти)чтобы выяснить, почему это происходит, и сейчас я делаю кучу снимков, чтобы найти различия в памяти между различными точками в рабочем цикле.Кажется, что после каждого цикла используемая память увеличивается примерно на 560 КБ.

Вот как это выглядит в инструменте инструментов:

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];

Спасибо за любую помощь, которую вы можете мне дать!

1 Ответ

2 голосов
/ 24 августа 2011

Предполагая, что вы обнаружили настоящую утечку, есть несколько идей:

  • Синхронизировать можно только в том случае, если существует вероятность появления новой информации (следите за изменениями в ~/Library/Application Support/AddressBook сkqueue или FSEvents).

  • Вы можете запустить синхронизацию в дочернем процессе, который вы периодически перезагружаете, или с предыдущим предложением, просто сделайте один запуск процесса, выполните синхронизацию и выйдите из него..

Службы Sync никогда не работали ужасно хорошо и с 10.7 устарели, так что я полагаю, что не будет много дополнительной работы.Я не думаю, что было бы пустой тратой времени на то, чтобы придумать отдельный пример и представить его как ошибку , особенно если это плохо.Кроме того, я бы предложил добавить еще одну ошибку в структуру адресной книги, объясняющую, что вы хотели бы иметь возможность проверять / получать уведомления о новой / обновленной информации.

...