Skip to content

Commit d18debd

Browse files
authored
NR-364636 fixing the persistent store memory leak (#345)
* 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
1 parent 472e2a8 commit d18debd

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

Agent/Analytics/NRMAAnalytics.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ - (id) initWithSessionStartTimeMS:(long long) sessionStartTime {
115115

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

118-
_eventManager = [[NRMAEventManager alloc] initWithPersistentStore:eventStore];
118+
_eventManager = [[NRMAEventManager alloc] initWithPersistentStore:[eventStore autorelease]];
119119
_attributeValidator = [[NRMAAttributeValidator alloc] init];
120120
_sessionAttributeManager = [[NRMASAM alloc] initWithAttributeValidator:_attributeValidator];
121121

Agent/Analytics/NRMAEventManager.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ - (BOOL)didReachMaxQueueTime:(NSTimeInterval)currentTimeMilliseconds {
7777
}
7878

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

8383
- (NSUInteger)getEvictionIndex {

Agent/Analytics/PersistentEventStore.m

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,34 @@ - (nonnull instancetype)initWithFilename:(NSString *)filename
4040
return self;
4141
}
4242

43+
- (void) dealloc {
44+
if(self.pendingBlock){
45+
dispatch_block_cancel(self.pendingBlock);
46+
}
47+
}
48+
4349
- (void)performWrite:(void (^)(void))writeBlock {
50+
__weak PersistentEventStore *weakSelf = self;
4451
dispatch_async(self.writeQueue, ^{
45-
if (self.pendingBlock != nil) {
46-
dispatch_block_cancel(self.pendingBlock);
52+
__strong PersistentEventStore *strongSelf = weakSelf;
53+
if (!strongSelf) { // Ensure strongSelf is not nil
54+
NRLOG_AGENT_WARNING(@"A block was scheduled but PersistentEventStore was deallocated before running");
55+
return;
4756
}
4857

49-
self.pendingBlock = dispatch_block_create(0, writeBlock);
58+
if (strongSelf.pendingBlock != nil) {
59+
dispatch_block_cancel(strongSelf.pendingBlock);
60+
}
61+
62+
strongSelf.pendingBlock = dispatch_block_create(0, writeBlock);
5063

51-
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self->_minimumDelay * NSEC_PER_SEC)), self->_writeQueue, self.pendingBlock);
64+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(strongSelf->_minimumDelay * NSEC_PER_SEC)), strongSelf->_writeQueue, ^{
65+
__strong PersistentEventStore *innerStrongSelf = weakSelf;
66+
if (innerStrongSelf && innerStrongSelf.pendingBlock) {
67+
innerStrongSelf.pendingBlock();
68+
innerStrongSelf.pendingBlock = nil; // Release the block after execution
69+
}
70+
});
5271
});
5372
}
5473

0 commit comments

Comments
 (0)