Skip to content
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

Issue/8199 memory leaks #8200

Merged
merged 4 commits into from
Aug 17, 2018
Merged

Issue/8199 memory leaks #8200

merged 4 commits into from
Aug 17, 2018

Conversation

malinajirka
Copy link
Contributor

@malinajirka malinajirka commented Aug 16, 2018

Fixes #8199

The app crashes when we try to load an image from a leaked context (after the activity has been destroyed).

This crash is quite rare, so it's almost impossible to reproduce it (usually occurs when the user has poor internet connection).

  1. Go to reader
  2. Open discovery
  3. Press back button -> the app sometimes crashes

You can reproduce this crash by removing the ReaderLikingUsersView.java.onDetachedFromWindow and adding Thread.sleep(3000); to LoadAvatarsTask .doInBackground(..)

  1. Go to Reader
  2. Open an article which has been liked by one user at least
  3. Scroll to the "Liked by" section
  4. Press back button -> the app sometimes crashes

@malinajirka malinajirka requested a review from theck13 August 16, 2018 08:37
@malinajirka malinajirka added this to the 10.7 ❄️ milestone Aug 16, 2018
Copy link
Contributor

@theck13 theck13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice solution to a not-so-easy crash! The code works as expected. I left a few comments about the code.

I was never able to reproduce the crash on develop without modifying the code. Since this crash is very rare with only two reported instances and 10.7 was released three days ago, I think these changes can wait until the 10.8 release.

private LoadAvatarsTask mLoadAvatarsTask;
private final int mLikeAvatarSz;
private final int mMarginAvatar;
private final int mMarginReader;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why the mMarginAvatar and mMarginReader variables were created. They're only used in the getMaxAvatars() like the marginAvatar and marginReader variables before. Is there an advantage to moving them from method to class variables?

Copy link
Contributor Author

@malinajirka malinajirka Aug 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a super minor optimization -> the resources are loaded only once, when the view is created. However, if you prefer to move it back to getMaxAvatars(), no problem at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getMaxAvatars() method is called only once, which means the marginAvatar and marginReader method variables would be loaded only once similar to the mMarginAvatar and mMarginReader class variables, so I'm not sure about the optimization there. Albeit rather small, the class variables will make a larger footprint though, so it could be argued the method variables are actually an optimization.

I usually create a class variable only if it needs to be used by multiple classes or methods. Otherwise, I use a method variable to help show that it's only required within that method and as a tiny size optimization. However, that's fairly subjective. Let me know if you would like to update mLikeAvatarSz, mMarginAvatar, and mMarginReader or leave them as is.

private final int mMaxAvatars;

LoadAvatarsTask(ReaderLikingUsersView view, long currentUserId, int likeAvatarSz,
int maxAvatars) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The maxAvatars parameter can be on the same line with the method and other parameters for better readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

ReaderPost post = posts[0];
ReaderUserIdList avatarIds = ReaderLikeTable.getLikesForPost(post);
return ReaderUserTable.getAvatarUrls(avatarIds, mMaxAvatars, mLikeAvatarSize,
mCurrentUserId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mCurrentUserId parameter can be on the same line with the method and other parameters for better readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@malinajirka
Copy link
Contributor Author

Thank you @theck13!

I was never able to reproduce the crash on develop without modifying the code. Since this crash is very rare with only two reported instances and 10.7 was released three days ago, I think these changes can wait until the 10.8 release.

I wasn't able to reproduce it without modifying the code either. What do you mean by with only two reported instances, I see 74 crashes in production which doesn't seem negligible. Do you really think we should postpone it to 10.8?

@malinajirka
Copy link
Contributor Author

Ohh I see, there are 2 reported instances on 10.7-rc1, but 74 instances on 10.6.

Copy link
Contributor

@theck13 theck13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by with only two reported instances, I see 74 crashes in production which doesn't seem negligible.

I was referring to your comment in the issue quoted below.

I've found two occurrences in the Fabric crashes.

If there are about 75 occurrences, then we can merge it into 10.7.

private LoadAvatarsTask mLoadAvatarsTask;
private final int mLikeAvatarSz;
private final int mMarginAvatar;
private final int mMarginReader;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getMaxAvatars() method is called only once, which means the marginAvatar and marginReader method variables would be loaded only once similar to the mMarginAvatar and mMarginReader class variables, so I'm not sure about the optimization there. Albeit rather small, the class variables will make a larger footprint though, so it could be argued the method variables are actually an optimization.

I usually create a class variable only if it needs to be used by multiple classes or methods. Otherwise, I use a method variable to help show that it's only required within that method and as a tiny size optimization. However, that's fairly subjective. Let me know if you would like to update mLikeAvatarSz, mMarginAvatar, and mMarginReader or leave them as is.

@malinajirka
Copy link
Contributor Author

malinajirka commented Aug 17, 2018

My reasoning was, that if we use this view in a RecyclerView, the method might be called every few ms. But since this is such a minor optimization and we don't use this view in a RecyclerView and I agree it looks cleaner with local variables, I've moved them back. :-)

Copy link
Contributor

@theck13 theck13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, I didn't think about the RecyclerView scenario. That's a good idea if we use this class for that in the future.

@theck13 theck13 merged commit f8077f7 into release/10.7 Aug 17, 2018
@theck13 theck13 deleted the issue/8199-memory-leaks branch August 17, 2018 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants