Skip to content

Commit

Permalink
NR-364636 fixing the persistent store memory leak (#345)
Browse files Browse the repository at this point in the history
* NR-364636 used weak reference to prevent retain cycles and strong references to ensure the object is not deallocated while being used within the block.

* Added a log when we try to run a block but was deallocated, added the pendingblock to cancel in dealloc also

* Changed to use NRLOG_AGENT_WARNING
  • Loading branch information
mbruin-NR authored Feb 5, 2025
1 parent 472e2a8 commit d18debd
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Agent/Analytics/NRMAAnalytics.mm
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ - (id) initWithSessionStartTimeMS:(long long) sessionStartTime {

PersistentEventStore *eventStore = [[PersistentEventStore alloc] initWithFilename:filename andMinimumDelay:.025];

_eventManager = [[NRMAEventManager alloc] initWithPersistentStore:eventStore];
_eventManager = [[NRMAEventManager alloc] initWithPersistentStore:[eventStore autorelease]];
_attributeValidator = [[NRMAAttributeValidator alloc] init];
_sessionAttributeManager = [[NRMASAM alloc] initWithAttributeValidator:_attributeValidator];

Expand Down
2 changes: 1 addition & 1 deletion Agent/Analytics/NRMAEventManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ - (BOOL)didReachMaxQueueTime:(NSTimeInterval)currentTimeMilliseconds {
}

NSTimeInterval oldestEventAge = currentTimeMilliseconds - oldestEventTimestamp;
return (oldestEventAge / 1000) + kBufferTimeSecondsLeeway >= maxBufferTimeSeconds;
return (oldestEventAge / kDefaultBufferSize) + kBufferTimeSecondsLeeway >= maxBufferTimeSeconds;
}

- (NSUInteger)getEvictionIndex {
Expand Down
27 changes: 23 additions & 4 deletions Agent/Analytics/PersistentEventStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,34 @@ - (nonnull instancetype)initWithFilename:(NSString *)filename
return self;
}

- (void) dealloc {
if(self.pendingBlock){
dispatch_block_cancel(self.pendingBlock);
}
}

- (void)performWrite:(void (^)(void))writeBlock {
__weak PersistentEventStore *weakSelf = self;
dispatch_async(self.writeQueue, ^{
if (self.pendingBlock != nil) {
dispatch_block_cancel(self.pendingBlock);
__strong PersistentEventStore *strongSelf = weakSelf;
if (!strongSelf) { // Ensure strongSelf is not nil
NRLOG_AGENT_WARNING(@"A block was scheduled but PersistentEventStore was deallocated before running");
return;
}

self.pendingBlock = dispatch_block_create(0, writeBlock);
if (strongSelf.pendingBlock != nil) {
dispatch_block_cancel(strongSelf.pendingBlock);
}

strongSelf.pendingBlock = dispatch_block_create(0, writeBlock);

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self->_minimumDelay * NSEC_PER_SEC)), self->_writeQueue, self.pendingBlock);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(strongSelf->_minimumDelay * NSEC_PER_SEC)), strongSelf->_writeQueue, ^{
__strong PersistentEventStore *innerStrongSelf = weakSelf;
if (innerStrongSelf && innerStrongSelf.pendingBlock) {
innerStrongSelf.pendingBlock();
innerStrongSelf.pendingBlock = nil; // Release the block after execution
}
});
});
}

Expand Down

0 comments on commit d18debd

Please sign in to comment.