Skip to content

Memory Leak in Heartbeat Tracking Mechanism #17

@viojoy

Description

@viojoy

Description

There's a potential memory leak in the heartbeat tracking mechanism. In both TJPNetworkManagerV1 and TJPConcurrentNetworkManager implementations, pendingHeartbeats dictionary tracks heartbeats by sequence number but never cleans up old entries.

Steps to Reproduce

  1. Establish a long-running connection with the server
  2. Let the app run for an extended period (multiple hours)
  3. Observe memory usage growth

Current Behavior

Entries in the pendingHeartbeats dictionary are added but never removed, causing the dictionary to grow indefinitely. Each heartbeat sequence number is stored with its timestamp, but these entries are never cleaned up.

Expected Behavior

Heartbeat entries should be removed from pendingHeartbeats once they're acknowledged or after a reasonable timeout period.

Code References

// In TJPConcurrentNetworkManager.m:
- (void)sendHeartbeat {
    // ...
    // Records heartbeat but never cleans it up
    self.pendingHeartbeats[@(_currentSequence)] = [NSDate date];
}

Impact

  • Memory usage increases over time for long-lived connections
  • Potential app crashes in memory-constrained environments
  • Performance degradation due to large dictionary size

Proposed Solution

Implement a cleanup mechanism for the pendingHeartbeats dictionary:

- (void)cleanupStaleHeartbeats {
    NSMutableArray *keysToRemove = [NSMutableArray array];
    NSDate *cutoffTime = [NSDate dateWithTimeIntervalSinceNow:-60]; // 1 minute timeout
    
    [self.pendingHeartbeats enumerateKeysAndObjectsUsingBlock:^(NSNumber *sequence, NSDate *timestamp, BOOL *stop) {
        if ([timestamp compare:cutoffTime] == NSOrderedAscending) {
            [keysToRemove addObject:sequence];
        }
    }];
    
    [keysToRemove enumerateObjectsUsingBlock:^(NSNumber *key, NSUInteger idx, BOOL *stop) {
        [self.pendingHeartbeats removeObjectForKey:key];
    }];
}

Call this method periodically or when handling heartbeat responses.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions