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

Fix memory leak in action view #27296

Closed
wants to merge 4 commits into from
Closed

Conversation

printercu
Copy link
Contributor

@printercu printercu commented Dec 7, 2016

#27273 for details.

Here I moved digest cache back to Digestor. In this way, it's possible not to clear DetailsKey cache, and keys for cached templates will be permanent.

I need to add testcase for not leaking memory.
I'm fixing action pack tests.

@rails-bot
Copy link

Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @kaspth (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

This repository is being automatically checked for code quality issues using Code Climate. You can see results for this analysis in the PR status below. Newly introduced issues should be fixed before a Pull Request is considered ready to review.

Please see the contribution instructions for more information.

@matthewd
Copy link
Member

matthewd commented Dec 7, 2016

Let's keep #27271 / 2380354 out of this PR

@printercu
Copy link
Contributor Author

No problem. I'll rebase when it's merged. Just don't want to resolve conflicts in the future. Do you plan to merge #27271?

@printercu printercu changed the title [WIP] Fix memory leak in action view Fix memory leak in action view Dec 7, 2016
@printercu
Copy link
Contributor Author

Seems like everything is ready.


@details_keys = Concurrent::Map.new
# Make hash uniq.
alias_method :hash, :object_id
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand this.

The whole point of this is to provide a key we can use to look up the value in the cache. If it has a new [hash] value each time, the cache is useless. 😕

Copy link
Contributor Author

@printercu printercu Dec 7, 2016

Choose a reason for hiding this comment

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

There are some details #27273 (comment)

It had been using hash before, but @tenderlove says it causes collisions.

Copy link
Contributor Author

@printercu printercu Dec 7, 2016

Choose a reason for hiding this comment

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

I don't know if everything will be fine with jRuby and other rubies.
Maybe I should change this to uuid?

UPD. Uh. I hope object_id means that it's uniq.

Copy link
Member

@matthewd matthewd Dec 7, 2016

Choose a reason for hiding this comment

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

My point is that it's not supposed to be unique. It's a cache key.

(I also see no such claim from @tenderlove.. where was that?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#23756

An object's hash value is not unique, so it's possible for this cache
key to produce colliding keys with no resolution. This commit move
cache on to the details key object itself, so we know that the digests
are always unique per details key object.

Copy link
Contributor Author

@printercu printercu Dec 7, 2016

Choose a reason for hiding this comment

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

I'm not really sure, how it can give collisions, while it also uses name, finder.rendered_format, dependencies in digests cache.

And name, prefix, partial, locals in templates cache.

However if we can have it uniq with single line, maybe it's good idea.

def get(*)
ActionView::Digestor::PerExecutionCacheExpiry.before(nil)
super
end
Copy link
Contributor Author

@printercu printercu Dec 7, 2016

Choose a reason for hiding this comment

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

@jeremy Can you please review it. It's about the feature of using template digestest in etag (#16527).

I had some tests failing (test_etag_reflects_implicit_template_digest and similar) with Expected Ok, got Not Modified and fixed them with this lines. Am I right, that it should work only in development, when digest cache is cleared on each request?

@printercu
Copy link
Contributor Author

Rebased branch is ready. I'll push it after discussion, to not miss open comments.

@matthewd
Copy link
Member

matthewd commented Dec 7, 2016

There are too many unrelated things changing in these commits, including rather cosmetic refactorings that later get reversed(?)

Can you please rebase it down to just the changes you believe are necessary to address the leak?

@printercu
Copy link
Contributor Author

Rebased.

@printercu printercu force-pushed the improving_av branch 2 times, most recently from 0988d78 to 3f24d5a Compare December 7, 2016 16:07
@printercu
Copy link
Contributor Author

Reverted back class << self in Digestor, so there are less changes.

@printercu printercu force-pushed the improving_av branch 3 times, most recently from 101f030 to bc2a624 Compare December 7, 2016 17:49
@printercu
Copy link
Contributor Author

printercu commented Dec 7, 2016

ActionCable is failing again, everything else is fine.

@printercu
Copy link
Contributor Author

@matthewd anything prevents merging this one?

@matthewd
Copy link
Member

There are still a mixture of changes that are either unrelated or unexplained... and I remain entirely unconvinced that the hash / object_id change makes any sense whatsoever.

@printercu
Copy link
Contributor Author

Can you please talk to @tenderlove about his notice on #hash.
What unrelated/unexplained changes do you mean? Here is single commit: 14f0778
If this one is blocker, I can remove it. Before, please just take a look on master https://github.com/rails/rails/blob/master/actionview/lib/action_view/lookup_context.rb#L115-L131 and find the difference in definition (it's present).

@printercu
Copy link
Contributor Author

Created sample app to compare patched version with 5.0.1: https://github.com/printercu/rails_dev_leak_example

@schneems
Copy link
Member

Are you still interested in getting this reviewed? Is this still an issue on master?

There is no need to clear DetailsKey cache,
so it should eliminate memory leak.
@printercu
Copy link
Contributor Author

I hope this is still useful. I've just rebased on master and run this tests https://github.com/rails/rails/pull/27296/files#diff-c3e4d6a7a9f83e67a19f2c90f3738443R71 - 2 of them are failed: not modified templates are recompiled on every request and memory is leaking.

@rails-bot
Copy link

rails-bot bot commented Dec 18, 2019

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
Thank you for your contributions.

@rails-bot rails-bot bot added the stale label Dec 18, 2019
@rails-bot rails-bot bot closed this Dec 25, 2019
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.

6 participants