Search code examples
objective-ccocoansrunloopcfrunloop

NSRunLoop is consuming a lot of cpu and memory


I have a infinite loop that drives my worker thread.

-(void) myThread
{
    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];   
    while(![myThread isCancelled])
    {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:600]];
    }
    [pool release];
}

but sometimes these threads are taking so much CPU(50-100%) and memory(1.5GB). when i sample the application in this state, i got following trace

    453 +[NSDate dateWithTimeIntervalSinceNow:]
          309 -[__NSPlaceholderDate initWithTimeIntervalSinceReferenceDate:]
            295 CFDateCreate
              268 _CFRuntimeCreateInstance
                115 malloc_zone_malloc
                  64 __spin_lock
                    64 __spin_lock
                  43 szone_malloc
                    22 tiny_malloc_from_free_list
                      22 tiny_malloc_from_free_list
                    19 szone_malloc
                    2 spin_unlock
                      2 spin_unlock
                  4 malloc_zone_malloc
                  3 dyld_stub__spin_unlock
                    3 dyld_stub__spin_unlock
                  1 dyld_stub__spin_lock
                    1 dyld_stub__spin_lock
                99 __bzero
                  99 __bzero
                29 malloc_size
                  23 szone_size
                    23 szone_size
                  6 malloc_size
                13 CFAllocatorAllocate
                  13 CFAllocatorAllocate
                12 _CFRuntimeCreateInstance
              20 CFDateCreate
              4 CFDateGetTypeID
                4 CFDateGetTypeID
              3 memset
                3 memset
            14 -[__NSPlaceholderDate initWithTimeIntervalSinceReferenceDate:]
          60 CFAbsoluteTimeGetCurrent
            48 gettimeofday
              38 __gettimeofday
                21 __nanotime
                  21 __nanotime
                17 __gettimeofday
              10 gettimeofday
            11 CFAbsoluteTimeGetCurrent
            1 __gettimeofday
              1 __gettimeofday
          47 +[NSObject alloc]
            25 objc_msgSend
              25 objc_msgSend
            11 +[NSDate allocWithZone:]
              8 +[NSObject self]
                8 +[NSObject self]
              3 +[NSDate allocWithZone:]
            7 +[NSObject alloc]
            2 +[__NSPlaceholderDate immutablePlaceholder]
              2 +[__NSPlaceholderDate immutablePlaceholder]
            2 dyld_stub_objc_msgSend
              2 dyld_stub_objc_msgSend
          24 +[NSDate dateWithTimeIntervalSinceNow:]
          7 objc_msgSend
            7 objc_msgSend
          4 CFMakeCollectable
            4 CFMakeCollectable
          1 dyld_stub_gettimeofday
            1 dyld_stub_gettimeofday
          1 dyld_stub_objc_msgSend
            1 dyld_stub_objc_msgSend
        354 -[NSRunLoop(NSRunLoop) runUntilDate:]
          307 -[NSRunLoop(NSRunLoop) runMode:beforeDate:]
            153 _CFRunLoopFinished
              125 __CFRunLoopFindMode
                110 CFSetGetValue
                  85 __CFSetFindBuckets1b
                    36 __CFSetFindBuckets1b
                    17 CFEqual
                      9 __CFRunLoopModeEqual
                        7 CFEqual
                          7 CFEqual
                        2 __CFRunLoopModeEqual
                      8 CFEqual
                    16 __CFStringHash
                      16 __CFStringHash
                    12 _CFHash
                      12 _CFHash
                    3 CFHash
                      3 CFHash
                    1 __CFRunLoopModeHash
                      1 __CFRunLoopModeHash
                  24 CFSetGetValue
                  1 CFEqual
                    1 CFEqual
                14 __CFRunLoopFindMode
                1 _CFRuntimeSetInstanceTypeID
                  1 _CFRuntimeSetInstanceTypeID
              12 _CFRunLoopFinished
              9 __CFRunLoopModeIsEmpty
                8 CFSetGetCount
                  8 CFSetGetCount
                1 __CFRunLoopModeIsEmpty
              6 __spin_lock
                6 __spin_lock
              1 spin_unlock
                1 spin_unlock
            82 -[NSCFString isEqual:]
              23 -[NSCFString isEqual:]
              22 objc_msgSend
                22 objc_msgSend
              17 CFStringGetLength
                17 CFStringGetLength
              9 CFStringGetCStringPtr
                9 CFStringGetCStringPtr
              6 NSClassFromObject
                2 -[NSObject class]
                  2 -[NSObject class]
                2 NSClassFromObject
                2 object_getClass
                  2 object_getClass
              3 object_getClass
                3 object_getClass
              1 dyld_stub_objc_msgSend
                1 dyld_stub_objc_msgSend
              1 dyld_stub_object_getClass
                1 dyld_stub_object_getClass
            37 _CFRunLoop0
              16 _CFRunLoop0
              12 CFDictionaryGetValue
                10 __CFDictionaryFindBuckets1a
                  10 __CFDictionaryFindBuckets1a
                2 CFDictionaryGetValue
              8 pthread_main_np
                8 pthread_main_np
              1 spin_unlock
                1 spin_unlock
            12 -[NSRunLoop(NSRunLoop) runMode:beforeDate:]
            11 __spin_lock
              11 __spin_lock
            6 dyld_stub_OSSpinLockUnlock
              6 dyld_stub_OSSpinLockUnlock
            3 CFRunLoopGetCurrent
              3 CFRunLoopGetCurrent
            1 dyld_stub_CFStringGetCStringPtr
              1 dyld_stub_CFStringGetCStringPtr
            1 dyld_stub_pthread_self
              1 dyld_stub_pthread_self
            1 spin_unlock
              1 spin_unlock
          25 -[__NSCFDate retain]
            15 OSAtomicCompareAndSwapLongBarrier
              8 __compare_and_swap32
                8 __compare_and_swap32
              7 OSAtomicCompareAndSwapLongBarrier
            4 -[__NSCFDate retain]
            4 _CFRetain
              4 _CFRetain
            1 CFRetain
              1 CFRetain
            1 __compare_and_swap32
              1 __compare_and_swap32
          14 -[NSRunLoop(NSRunLoop) runUntilDate:]
          7 objc_msgSend
            7 objc_msgSend
          1 dyld_stub__CFRunLoopFinished
            1 dyld_stub__CFRunLoopFinished
        51 objc_msgSend
          51 objc_msgSend
        39 -[NSObject(NSObject) autorelease]
          28 __NSAutoreleaseObject
            24 __NSAutoreleaseObject
            4 _NSAPAddPage
              2 _NSAPAddPage
              2 malloc
                2 malloc_zone_malloc
                  2 szone_malloc
                    2 small_malloc_from_free_list
                      1 small_free_list_add_ptr
                        1 small_free_list_add_ptr
                      1 small_malloc_from_free_list
          8 NSAutoreleaseObject
            7 NSAutoreleaseObject
            1 objc_collecting_enabled
              1 objc_collecting_enabled
          1 -[NSObject(NSObject) autorelease]
          1 dyld_stub_pthread_getspecific
            1 dyld_stub_pthread_getspecific
          1 pthread_getspecific
            1 pthread_getspecific
        19 +[NSRunLoop(NSRunLoop) currentRunLoop]
          14 +[NSThread currentThread]
            13 +[NSThread currentThread]
            1 pthread_getspecific
              1 pthread_getspecific
          3 +[NSRunLoop(NSRunLoop) currentRunLoop]
          1 dyld_stub_pthread_getspecific
            1 dyld_stub_pthread_getspecific
          1 pthread_getspecific
            1 pthread_getspecific
        14 -[NSThread _rl]
          14 -[NSThread _rl]
        13 -[MessageSendingModule startSender]
        12 -[NSThread isCancelled]
          12 -[NSThread isCancelled]
        9 OSAtomicCompareAndSwapLongBarrier
          5 OSAtomicCompareAndSwapLongBarrier
          4 __compare_and_swap32
            4 __compare_and_swap32
        6 CFRelease
          6 CFRelease
        6 _CFRelease
          6 _CFRelease
        1 -[__NSCFDate release]
          1 -[__NSCFDate release]
        1 NSAutoreleaseObject
          1 NSAutoreleaseObject
        1 dyld_stub_objc_msgSend
          1 dyld_stub_objc_msgSend
      115 objc_msgSend
        115 objc_msgSend
      4 dyld_stub_objc_msgSend
        4 dyld_stub_objc_msgSend
      1 CFRelease
        1 CFRelease

can anyone please help me out?


Solution

  • An empty runloop (a runloop without any input sources or timers) will immediately return from runUntilDate:.

    If you want to keep the thread around and service it's runloop, you could just add a timer to the runloop.

    Is there any reason you're not using libdispatch for your thread dispatching? This would avoid the troubles of managing the threads and runloop yourself.