JDK-8317692 : jcmd GC.heap_dump performance regression after JDK-8292818
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 21,22
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-10-06
  • Updated: 2023-10-24
  • Resolved: 2023-10-19
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 22
22 masterFixed
Related Reports
Blocks :  
Relates :  
Relates :  
Description
JDK-8292818 changed how field metadata (e.g. access flags) is accessed to streaming access. That means accessing a field of a InstanceKlass by index has to go through the stream to find the appropriate field.

This causes a performance regression in jcmd GC.heap_dump, which uses FieldStream from reflectionUtils.hpp. This implementation has two flaws in combination with the change from JDK-8292818:

1. It uses field indexes to access data, e.g. _klass->field_access_flags(_index) to get a field's access flags.
2. It traverses the fields in reverse order. The way how the metadata is stored now only allows for efficient forward traversal.

As an example, running the attached Java file and creating a heap dump takes (on my machine):
- 2-3 seconds on Java 17
- ~20 seconds on Java 21

FieldStream cannot directly be replaced by the implementations from fieldStreams.hpp because it additionally traverses supertypes.

The proposed fix is to add field streaming with supertype traversal to fieldStreams.hpp. This way, other usages of FIeldStream are unaffected in behavior. The new implementation does foward traversal over the fields but keeps the order in which supertypes visited from FieldStream. This way, the produced heap dump will still conform to the hprof format.

Relevant mailing list discussion: https://mail.openjdk.org/pipermail/serviceability-dev/2023-October/051571.html
Comments
Okay, now I see the 21u PR, and bots linked it here. And I see your "Fix Request" comment here, good. So the only thing that is missing is putting the jdk21u-fix-request tag back. Then we wait for maintainer approval. When that happens, bots would mark 21u PR as ready for integration.
20-10-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk21u/pull/274 Date: 2023-10-20 08:21:41 +0000
20-10-2023

Hi Aleksey, I tried to follow https://openjdk.org/projects/jdk-updates/approval.html, but maybe I misunderstood things there. I now created the PR in the jdk21u repo. Please let me know if something is missing.
20-10-2023

Fix Request This fix heavily improves the performance of heap dump functionality via jcmd. Even for below 1GB heaps, I encountered situations where a heap dump took multiple minutes due to the regression. With this change, the duration is now back to a few seconds. The change only affects the heapDumper functionality and therefore I expect it to have a low impact. It also adds tests that ensure all instance fields are present in heap dumps. The patch applies cleanly.
20-10-2023

Hannes, we need to follow the backporting process to get it to 21u; it is not enough to just put the jdk21u-fix-request label, unfortunately. It would probably be enough to go to the changeset (https://git.openjdk.org/jdk/commit/8f5f44070a7c6dbbbd1005f9d0af5ab7c35179df), say `/backport jdk21u` in comments there, and then follow bots instructions. I will remove jdk21u-fix-request meanwhile as to not confuse the jdk21u maintainers.
20-10-2023

Changeset: 8f5f4407 Author: Hannes Greule <hgreule@openjdk.org> Committer: David Holmes <dholmes@openjdk.org> Date: 2023-10-19 23:24:28 +0000 URL: https://git.openjdk.org/jdk/commit/8f5f44070a7c6dbbbd1005f9d0af5ab7c35179df
19-10-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/16083 Date: 2023-10-06 20:56:13 +0000
06-10-2023

Moved to hotspot/runtime for initial triage.
06-10-2023