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

[Native Image] Issues with GC Behavior in GraalVM Native Image (21 CE) for Spring Boot Application #10499

Open
1 of 2 tasks
Duwei92 opened this issue Jan 16, 2025 · 5 comments
Assignees

Comments

@Duwei92
Copy link

Duwei92 commented Jan 16, 2025

Describe the Issue

I am using GraalVM 21 CE to compile a large Spring Boot application into a native image. The compilation uses default parameters, with the garbage collection strategy set to adaptive. I have encountered the following issues:

1.When running the application with both -Xms and -Xmx parameters set to 640m, only the -Xmx parameter takes effect. After running for a while, I noticed through VisualVM that the memory usage is compressed to a very small value, and garbage collection occurs very frequently (minor GC every few seconds, full GC every one or two minutes).

Image

2.After some time, the application experiences consecutive full GCs, leading to a freeze. During these consecutive GCs, I observed that the Eden space is only 4MB.

From my research, I understand that GraalVM adopts an aggressive GC strategy to minimize memory usage. However, I prefer a more stable memory usage pattern similar to a regular JVM, where memory is not returned to the system after every GC cycle, as this frequent fluctuation increases CPU usage.

Do you have any recommendations, such as parameter tuning, to achieve more stable memory usage?

Using the latest version of GraalVM can resolve many issues.

GraalVM Version

CE 21

Operating System and Version

Darwin appledeMacBook-Pro.local 24.1.0 Darwin Kernel Version 24.1.0: Thu Oct 10 21:02:27 PDT 2024; root:xnu-11215.41.3~2/RELEASE_X86_64 x86_64

Troubleshooting Confirmation

Run Command

./demo -Xms768m -Xmx768m -XX:MaxHeapFree=200000000 -XX:+PrintGC -XX:+VerboseGC -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=127.0.0.1

Expected Behavior

I hope it uses a more fixed amount of memory while reducing GC (including minor GC and full GC) and avoiding consecutive GCs.

Actual Behavior

here are frequent GCs, and the heap memory keeps changing. Each GC returns memory to the system, and occasionally multiple consecutive GCs occur, causing the system to freeze.

Steps to Reproduce

1 use the demo pargrams:
mport org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.concurrent.*;

@RestController
public class Hello {

private static Executor executor = new ThreadPoolExecutor(2, 2, 10, TimeUnit.HOURS, new ArrayBlockingQueue<>(100));
private static LinkedHashMap LRU = new LinkedHashMap(128, 0.75f, true);
@GetMapping(path = "/hello")
public String sayHello() {
    //System.out.println("hello");
    return "haha hello";
}

@GetMapping(path = "/addMemory")
public String addMemory() throws Exception {
    //System.out.println("addMemory");
    for (int i = 0; i < 100; i++) {
        Thread.sleep(10);
        executor.execute(new Runnable() {
            @Override
            public void run() {
                int[] array = new int[ThreadLocalRandom.current().nextInt(1,100000)];
                Arrays.fill(array, ThreadLocalRandom.current().nextInt());
                synchronized (LRU) {
                    if(LRU.size()>128){
                        LRU.remove(LRU.keySet().iterator().next());
                    }
                    if(LRU.size()>4096){
                        LRU.clear();
                    }
                    LRU.put(new Object(), array);
                }

                try{
                    Thread.sleep(10);
                }catch (Exception ignore){

                }
            }
        });
    }

    return "done";
}

}

  1. use graalvm 21 CE, with compile params:
    Args = -H:Class=com.example.demo.DemoApplication
    --report-unsupported-elements-at-runtime
    --no-fallback
    --install-exit-handlers --strict-image-heap
    --enable-monitoring=heapdump,jmxserver,jmxclient,jvmstat
    -H:+UnlockExperimentalVMOptions \

3.run with cmd:
./demo -Xms768m -Xmx768m -XX:MaxHeapFree=200000000 -XX:+PrintGC -XX:+VerboseGC -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=127.0.0.1

4.use visualVM monitor the cpu and heap, see the GC print

Additional Context

No response

Run-Time Log Output and Error Messages

No response

@selhagani
Copy link
Member

Hi @Duwei92,

Thank you for reaching out to us!
Could you please try retesting with our latest GraalVM release? you can find it here: https://github.com/graalvm/graalvm-ce-builds/releases/

@selhagani selhagani self-assigned this Jan 20, 2025
@Duwei92
Copy link
Author

Duwei92 commented Jan 20, 2025

hi,Our current system is using the 21 CE version as the final decision. Is there any other optimization approach or analysis method for this situation? For example, adjusting some parameters to optimize the GC performance?

Of course, I will also try testing with the latest version, but this should not change our current decision.

@Duwei92
Copy link
Author

Duwei92 commented Jan 20, 2025

Image

Image

The above partial GC logs suggest that continuous GC was triggered, and at the same time, the Eden space became very small.

@Duwei92
Copy link
Author

Duwei92 commented Jan 21, 2025

@selhagani Do you have any troubleshooting and optimization ideas?

@selhagani
Copy link
Member

Did you get a chance to test with the latest available version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants