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 和内存的主要内容,如果未能解决你的问题,请参考以下文章
yarn install and build 消耗 100% CPU 和内存 95%
rmi.transport.tcp.tcptransport Connectionhandler 消耗大量 CPU