-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
8168469: Memory leak in JceSecurity #13658
Conversation
👋 Welcome back sercher! A progress list of the required criteria for merging this PR into |
Webrevs
|
@valeriepeng Could you please take a look at this change? |
Ok, I will take a look. |
if (verifyingProviders.get(p) != null) { | ||
// recursion; return failure now | ||
return new NoSuchProviderException | ||
throw new IllegalStateException | ||
("Recursion during verification"); |
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.
nit: no need for repeating error message here since it's not really used in line 242 anyway.
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.
Thank you! I updated the PR.
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.
Rest looks good to me. Thanks!
@sercher This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 285 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@valeriepeng) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
/integrate |
/sponsor |
Going to push as commit a284920.
Your commit was automatically rebased without conflicts. |
@valeriepeng @sercher Pushed as commit a284920. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Hi all,
I would like to propose a patch for an issue discussed in [1][2] that fixes an OOME in the current code base. The issue appears when a SunJCE provider object reference is stored in a non-static variable, which eventually leads to a Java heap OOME.
The solution proposed earlier [1] raised a concern that the identity of provider objects may be somehow broken when using
WeakHashMap<Class<? extends Provider>, Object>
instead ofIdentityHashMap<Provider, Object>
. The solution hasn't been integrated that time. Later in 2019 a performance improvement was introduced with [3][4] that changedIdentityHashMap
toConcurrentHashMap
ofIdentityWrapper<Provider>
objects that maintained the object identity while improved performance.The solution being proposed keeps up with performance improvement in [3], further narrowing the synchronization down to the hash table node, avoids lambdas that may cause startup time regressions and maintains providers identity using
WeakIdentityWrapper
that extendsWeakReference<Object>
while avoiding depletion of Java heap by using weak pointers as the mapping key. Once a provider object becomes weakly reachable it is queued along with its reference object to theReferenceQueue
(a new static member inJceSecurity
). Theequals()
method of theWeakIdentityWrapper
will never match a new wrapper object to anything inside the hash table after the corresponding element'sWeakReference.get()
returned null. This leads to accumulating "empty" elements in the hash table. The new static functionexpungeStaleWrappers()
drops the "empty" elements queued by GC each time thegetVerificationResult()
method is called.ConcurrentHashMap
'scomputeIfAbsent()
does (partially) detect recursive updates for keys that are being added to empty bins. For such keys anIllegalStateException
is thrown prior to recursive execution of themappingFunction
. For nodes that are added to existing TreeBins or linked lists, in which case no recursion detection is done prior to callingmappingFunction
, the recursion detection relies on old method withIdentityMap
of Providers.I include a test that runs under memory constrained conditions (128M) that hits the heap limit in current VMs where it is impossible to reclaim providers' memory (unless they've been cached under weak references). The updated jdk versions pass the test.
Testing: jtreg + JCK on a downport of the patch to JDK 17 with no regressions
[1] https://mail.openjdk.org/pipermail/security-dev/2016-October/015024.html
[2] https://bugs.openjdk.org/browse/JDK-8168469
[3] https://bugs.openjdk.org/browse/JDK-7107615
[4] 74d45e4
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/13658/head:pull/13658
$ git checkout pull/13658
Update a local copy of the PR:
$ git checkout pull/13658
$ git pull https://git.openjdk.org/jdk.git pull/13658/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 13658
View PR using the GUI difftool:
$ git pr show -t 13658
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/13658.diff
Webrev
Link to Webrev Comment