Skip to content

Conversation

@wankunde
Copy link
Contributor

@wankunde wankunde commented Oct 21, 2025

What changes were proposed in this pull request?

This PR aims to add utility functions to detect JVM GCs.

Why are the changes needed?

To provide a general capability to optimize based on the GC types.

Does this PR introduce any user-facing change?

No

How was this patch tested?

Manual review.

Was this patch authored or co-authored using generative AI tooling?

No

@github-actions github-actions bot added the CORE label Oct 21, 2025
@pan3793
Copy link
Member

pan3793 commented Oct 21, 2025

According to https://dev.java/learn/jvm/tool/garbage-collection/zgc-deepdive/

ZGC has three different sizes for regions; small, medium, and large.

Seems the waste is not as bad as G1, but this change still benefits ZGC memory utilization.

Have you used Shenandoah GC? According to #34846 (review), I think we should apply the same change to Shenandoah GC.

The same behavior affects the Shenandoah GC as well since it reuses the G1 region-based heap structure.

*/
lazy val isZGC: Boolean = checkUseGC("UseZGC")

def checkUseGC(useGCObjectStr: String): Boolean = {
Copy link
Member

Choose a reason for hiding this comment

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

Hi, @wankunde . Thank you for making a PR. Could you spin off this contribution? This sounds like a good idea to add a general utility function to detect GCs. We can proceed this one first.

As @pan3793 mentioned, if you can generalize more to detect other GCs, it would be a perfect contribution.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your review. For this PR, I will only add a function to detect GCs for G1, ZGC and ShenandoahGC

@wankunde
Copy link
Contributor Author

wankunde commented Oct 22, 2025

According to https://dev.java/learn/jvm/tool/garbage-collection/zgc-deepdive/

ZGC has three different sizes for regions; small, medium, and large.

Seems the waste is not as bad as G1, but this change still benefits ZGC memory utilization.

Have you used Shenandoah GC? According to #34846 (review), I think we should apply the same change to Shenandoah GC.

The same behavior affects the Shenandoah GC as well since it reuses the G1 region-based heap structure.

Hi, @pan3793, @dongjoon-hyun run the previous test with -Xmx1000m and different GCs, I think this optimization is also helpful for ZGC and ShenandoahGC.

Test code: https://gist.githubusercontent.com/wankunde/b7cf073b31f3a4bf5b525ab4a6b1f700/raw/85db977f5ef8609db27ced49d10ace9a248433c1/TestBlockSize.java

Test result:

Max allocated size without optimization Max allocated size with optimization
G1GC 817889280 1019211984
ZGC 671088640 1006629120
ShenandoahGC 855638016 964686240

Detail test result: https://gist.github.com/wankunde/6f3b6ed8abaa247307469ab5a4fae2bb

@wankunde
Copy link
Contributor Author

@pan3793

ZGC has three different sizes for regions; small, medium, and large.

Large Regions
Large regions are reserved for humongous objects and are tightly fitted in 2 MB increments to the object's size.

For ZGC, if we allocate a 4MB long array, approximately 2MB / (4MB + 2MB) ~ 33% of memory is wasted;
if we allocate a 16MB long array, approximately 2MB / (16MB + 2MB) ~ 11% of memory are wasted.

Test ZGC with -Xmx1000m without this optimization:

[0.580s][info][gc] GC(11) Major Collection (Allocation Stall) 988M(99%)->996M(100%) 0.030s
Total allocated size: 889192448
[0.581s][info][gc] GC(12) Minor Collection (Allocation Stall)
[0.587s][info][gc] Relocation Stall (Attach Listener) 0.053ms
[0.587s][info][gc] GC(12) Minor Collection (Allocation Stall) 996M(100%)->1000M(100%) 0.005s
[0.587s][info][gc] GC(13) Major Collection (Allocation Stall)
[0.593s][info][gc] GC(14) Minor Collection (Allocation Stall)
[0.597s][info][gc] GC(14) Minor Collection (Allocation Stall) 996M(100%)->996M(100%) 0.004s
[0.606s][info][gc] GC(13) Major Collection (Allocation Stall) 1000M(100%)->992M(99%) 0.019s
[0.606s][info][gc] Allocation Stall (main) 24.366ms
[0.606s][info][gc] Out Of Memory (main)
Terminating due to java.lang.OutOfMemoryError: Java heap space

@wankunde wankunde changed the title [SPARK-53966][CORE] Reduce default page size by LONG_ARRAY_OFFSET if ZGC and ON_HEAP are used [SPARK-53966][CORE] Add a general utility function to detect GC type Oct 22, 2025
@dongjoon-hyun dongjoon-hyun changed the title [SPARK-53966][CORE] Add a general utility function to detect GC type [SPARK-53966][CORE] Add utility functions to detect JVM GC Oct 23, 2025
@dongjoon-hyun dongjoon-hyun changed the title [SPARK-53966][CORE] Add utility functions to detect JVM GC [SPARK-53966][CORE] Add utility functions to detect JVM GCs Oct 23, 2025
Copy link
Member

@dongjoon-hyun dongjoon-hyun left a comment

Choose a reason for hiding this comment

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

+1, LGTM. Thank you for revision, @wankunde .

I revised the PR title and description according to your latest code change.

Also, thank you, @pan3793 , too.

@dongjoon-hyun
Copy link
Member

I manually verified. Merged to master for Apache Spark 4.1.0-preview3.

$ bin/spark-shell --conf "spark.driver.extraJavaOptions=-XX:+UseShenandoahGC"
WARNING: Using incubator modules: jdk.incubator.vector
Using Spark's default log4j profile: org/apache/spark/log4j2-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 4.1.0-SNAPSHOT
      /_/

Using Scala version 2.13.17 (OpenJDK 64-Bit Server VM, Java 21.0.8)
Type in expressions to have them evaluated.
Type :help for more information.
25/10/23 09:11:40 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Spark context Web UI available at http://localhost:4040
Spark context available as 'sc' (master = local[*], app id = local-1761235900588).
Spark session available as 'spark'.

scala> org.apache.spark.util.Utils.isG1GC
val res0: Boolean = false

scala> org.apache.spark.util.Utils.isZGC
val res1: Boolean = false

scala> org.apache.spark.util.Utils.isShenandoahGC
val res2: Boolean = true

sarutak pushed a commit that referenced this pull request Oct 23, 2025
### What changes were proposed in this pull request?

This PR aims to support `isSerialGC` and `isParallelGC` additionally as a follow-up of the following PR.
- #52678

### Why are the changes needed?

- To be exhaustive (up to Java 25 environment)
- Note that `UseEpsilonGC` is excluded because it's not a production-purpose GC.

### Does this PR introduce _any_ user-facing change?

No, these are new APIs.

### How was this patch tested?

Pass the CIs and manual review.

### Was this patch authored or co-authored using generative AI tooling?

No.

Closes #52708 from dongjoon-hyun/SPARK-53966.

Authored-by: Dongjoon Hyun <[email protected]>
Signed-off-by: Kousuke Saruta <[email protected]>
@wankunde wankunde deleted the zgc branch October 29, 2025 09:52
huangxiaopingRD pushed a commit to huangxiaopingRD/spark that referenced this pull request Nov 25, 2025
### What changes were proposed in this pull request?

This PR aims to add utility functions to detect JVM GCs.

### Why are the changes needed?

To provide a general capability to optimize based on the GC types.

### Does this PR introduce _any_ user-facing change?

No

### How was this patch tested?

Manual review.

### Was this patch authored or co-authored using generative AI tooling?

No

Closes apache#52678 from wankunde/zgc.

Authored-by: WanKun <[email protected]>
Signed-off-by: Dongjoon Hyun <[email protected]>
huangxiaopingRD pushed a commit to huangxiaopingRD/spark that referenced this pull request Nov 25, 2025
### What changes were proposed in this pull request?

This PR aims to support `isSerialGC` and `isParallelGC` additionally as a follow-up of the following PR.
- apache#52678

### Why are the changes needed?

- To be exhaustive (up to Java 25 environment)
- Note that `UseEpsilonGC` is excluded because it's not a production-purpose GC.

### Does this PR introduce _any_ user-facing change?

No, these are new APIs.

### How was this patch tested?

Pass the CIs and manual review.

### Was this patch authored or co-authored using generative AI tooling?

No.

Closes apache#52708 from dongjoon-hyun/SPARK-53966.

Authored-by: Dongjoon Hyun <[email protected]>
Signed-off-by: Kousuke Saruta <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants