NSRunLoop 正在消耗大量的 cpu 和内存

Posted

技术标签:

【中文标题】NSRunLoop 正在消耗大量的 cpu 和内存【英文标题】:NSRunLoop is consuming a lot of cpu and memory 【发布时间】:2012-04-20 11:29:50 【问题描述】:

我有一个无限循环驱动我的工作线程。

-(void) myThread

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

但有时这些线程会占用大量 CPU (50-100%) 和内存 (1.5GB)。当我在这种状态下对应用程序进行采样时,我得到了以下跟踪

    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

谁能帮帮我?

【问题讨论】:

在我看来你只是给它发送了太多的工作。 【参考方案1】:

一个空的runloop(一个没有任何输入源或定时器的runloop)将立即从runUntilDate:返回。

如果您想保留线程并为其运行循环提供服务,您可以在运行循环中添加一个计时器。

您是否有任何理由不使用 libdispatch 进行线程调度?这样就避免了自己管理线程和runloop的麻烦。

【讨论】:

为了保持线程活跃,我使用while循环。我对libdispatch不太了解? +1 用于空的 runloop。在实现时,这只是一个紧凑的 while 循环。 @JeremyP 所以我应该在运行循环中添加计时器吗? @Parag:因为这样运行循环将等待计时器到期。事实上,它不一定是定时器,任何运行循环事件都可以。

以上是关于NSRunLoop 正在消耗大量的 cpu 和内存的主要内容,如果未能解决你的问题,请参考以下文章

列出所有进程及其当前的内存和 CPU 消耗?

yarn install and build 消耗 100% CPU 和内存 95%

烧瓶应用程序 - 100% 的内存和 CPU 消耗

rmi.transport.tcp.tcptransport Connectionhandler 消耗大量 CPU

SQL Server 2014下Database Mail Engine进程消耗大量CPU资源

为啥在嵌入式 HSQLDB 上运行更新查询会消耗大量内存?