JDK-8277072 : ObjectStreamClass caches keep ClassLoaders alive
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io:serialization
  • Affected Version: 8,11,17,18,19
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2021-11-12
  • Updated: 2023-11-08
  • Resolved: 2021-12-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 17 JDK 18 JDK 19
11.0.16Fixed 17.0.4Fixed 18.0.2Fixed 19 b02Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The caches in ObjectStreamClass basically map WeakReference<Class> to SoftReference<ObjectStreamClass>, where the ObjectStreamClass also references the same Class. That means that the cache entry, and thus the class and its class-loader, will not get reclaimed, unless the GC determines that memory pressure is very high.

However, this seems bogus, because that unnecessarily keeps ClassLoaders and all its classes alive much longer than necessary: as soon as a ClassLoader (and all its classes) become unreachable, there is no point in retaining the stuff in OSC's caches.

This can be demonstrated by compiling the attached .java files, and run:
java TestObjectStreamClass

Comments
Hi [~rkennke], ok, then better backport JDK-8278065 too.
15-03-2022

[~goetz] I am not 100% sure about JDK-8278065, I believe there is a similar leak like this one here (JDK-8277072), but much smaller because it's only one Boolean object per cached Class, and also much rarer (afaiu, this code path is only used when running with SecurityManager).
14-03-2022

[~rkennke], can you please make a dependent pull request for JDK-8280041? I'm not sure JDK-8278065 is needed in 17, especially not in 11. It's only a cleanup, right?
11-03-2022

Fix-request (jdk11u): This fixes a memory leak under certain conditions. The fix has baked in JDK19, and I will backport the follow-ups (JDK-8280041 and JDK-8278065) as soon as this backport is integrated (they depend on this one). Backport is not clean, there have been some minor differences in context.
09-03-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk18u/pull/36 Date: 2022-03-09 16:11:13 +0000
09-03-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk11u-dev/pull/869 Date: 2022-03-09 16:09:31 +0000
09-03-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk17u-dev/pull/210 Date: 2022-03-09 14:02:30 +0000
09-03-2022

Fix-request (jdk18u, jdk17u): This fixes a memory leak under certain conditions. The fix has baked in JDK19, and I will backport the follow-ups (JDK-8280041 and JDK-8278065) as soon as this backport is integrated (they depend on this one). Backport is clean.
09-03-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk18/pull/117 Date: 2022-03-09 13:11:27 +0000
09-03-2022

Changeset: 8eb453ba Author: Roman Kennke <rkennke@openjdk.org> Date: 2021-12-10 16:24:16 +0000 URL: https://git.openjdk.java.net/jdk/commit/8eb453baebe377697286f7eb32280ca9f1fd7775
10-12-2021