-
Notifications
You must be signed in to change notification settings - Fork 886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix memory leaks for IoT #1037
Fix memory leaks for IoT #1037
Conversation
@@ -99,7 +99,7 @@ | |||
/** | |||
An optional associated object (nil by default). | |||
*/ | |||
@property(nonatomic, strong) NSObject *associatedObject; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this change.
@@ -639,6 +639,16 @@ - (void)openStreams:(id)sender | |||
[defaultRunLoopTimer invalidate]; | |||
|
|||
if (!self.runLoopShouldContinue ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. The connectionAgeTimer will self terminate once the max age has been reached, but if a disconnect is issued before then, it will continue to run and hold on to the object reference.
I think we can simplify this by just doing this after line 639. Thoughts?
if (self.connectionAgeTimer != nil ) {
[self.connectionAgeTimer invalidate];
self.connectionAgeTimer = nil;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we need to move the invalidate
call because of the documentation below.
From https://developer.apple.com/documentation/foundation/nstimer/1415405-invalidate?language=objc
Special Considerations
You must send this message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.
Updated PR at #1175 |
After removing an
AWSIoTDataManager
, theAWSIoTDataManager
,AWSIoTMQTTClient
,AWSURLSessionManager
and other related entities were leaked.This fixes a retain cycle between the
AWSIoTMQTTClient
where it held a strong reference to theassociatedObject
theAWSIoTDataManager
which was holding a strong reference to themqttClient
. This makes theassociatedObject
reference weak.If an
AWSIoTDataManager
was disconnected before theconnectionAgeInSeconds
exceeded theminimumConnectionTime
theconnectionAgeTimer
was never invalidated and held a strong reference to theAWSIoTMQTTClient
(e.g.self
passed to the timer on creation of the timer). This fixes the issue by issuing aninvalidate
to the timer on the correct thread in the event the user requests a disconnect before reaching theminimumConnectionTime
.The
AWSURLSessionManager
creates and passesself
to anNSURLSession
but never invalidated the session to release the strong reference toself
.AWSNetworking
could be released but theAWSURLSessionManager
leaked being held by theNSURLSession
. This is fixed by having theAWSNetworking
let theAWSURLSessionManager
know it needs to invalidate the session when it is being released, as none of them should be needed after theAWSNetworking
creating them is released.