Skip to content

Commit

Permalink
Deallocate objects on a serial queue specific for deallocation (faceb…
Browse files Browse the repository at this point in the history
…ookarchive#1737)

[Performance] Prevent GCD thread explosion due to object deallocation workloads (serial deallocation queue).
  • Loading branch information
maicki authored and appleguy committed Jun 17, 2016
1 parent efab1a4 commit aa5d730
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 4 deletions.
2 changes: 1 addition & 1 deletion AsyncDisplayKit/ASMultiplexImageNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ - (void)_clearImage
BOOL shouldReleaseImageOnBackgroundThread = imageSize.width > kMinReleaseImageOnBackgroundSize.width ||
imageSize.height > kMinReleaseImageOnBackgroundSize.height;
if (shouldReleaseImageOnBackgroundThread) {
ASPerformBlockOnBackgroundThread(^{
ASPerformBlockOnDeallocationQueue(^{
image = nil;
});
}
Expand Down
2 changes: 1 addition & 1 deletion AsyncDisplayKit/ASNetworkImageNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ - (void)_clearImage
BOOL shouldReleaseImageOnBackgroundThread = imageSize.width > kMinReleaseImageOnBackgroundSize.width ||
imageSize.height > kMinReleaseImageOnBackgroundSize.height;
if (shouldReleaseImageOnBackgroundThread) {
ASPerformBlockOnBackgroundThread(^{
ASPerformBlockOnDeallocationQueue(^{
image = nil;
});
}
Expand Down
2 changes: 1 addition & 1 deletion AsyncDisplayKit/ASTextNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ - (void)_invalidateRenderer
// actually dealloc.
__block ASTextKitRenderer *renderer = _renderer;

ASPerformBlockOnBackgroundThread(^{
ASPerformBlockOnDeallocationQueue(^{
renderer = nil;
});
_renderer = nil;
Expand Down
9 changes: 8 additions & 1 deletion AsyncDisplayKit/Private/ASInternalHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ ASDISPLAYNODE_EXTERN_C_BEGIN

BOOL ASSubclassOverridesSelector(Class superclass, Class subclass, SEL selector);
BOOL ASSubclassOverridesClassSelector(Class superclass, Class subclass, SEL selector);

/// Dispatches the given block to the main queue if not already running on the main thread
void ASPerformBlockOnMainThread(void (^block)());
void ASPerformBlockOnBackgroundThread(void (^block)()); // DISPATCH_QUEUE_PRIORITY_DEFAULT

/// Dispatches the given block to a background queue with priority of DISPATCH_QUEUE_PRIORITY_DEFAULT if not already run on a background queue
void ASPerformBlockOnBackgroundThread(void (^block)()); // DISPATCH_QUEUE_PRIORITY_DEFAULT

/// Dispatches a block on to a serial queue that's main purpose is for deallocation of objects on a background thread
void ASPerformBlockOnDeallocationQueue(void (^block)());

CGFloat ASScreenScale();

Expand Down
11 changes: 11 additions & 0 deletions AsyncDisplayKit/Private/ASInternalHelpers.mm
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ void ASPerformBlockOnBackgroundThread(void (^block)())
}
}

void ASPerformBlockOnDeallocationQueue(void (^block)())
{
static dispatch_queue_t queue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create("org.AsyncDisplayKit.deallocationQueue", DISPATCH_QUEUE_SERIAL);
});

dispatch_async(queue, block);
}

CGFloat ASScreenScale()
{
static CGFloat __scale = 0.0;
Expand Down

0 comments on commit aa5d730

Please sign in to comment.