Super Java Host
  1. Home
  2. Guides
  3. Java app slow or high CPU

Java app slow or using high CPU on a VPS

Slow can mean four different things: the server is starved, the JVM is busy with garbage collection, one thread is looping, or the application waits for something else. Each has a quick test.

1. Look at the server first

top
vmstat 2 5
free -m
What you seeWhat it means
High us, java at 100 percent or more per coreThe JVM is busy computing: a loop, GC or real load. Go to step 2 to 4
High wa (I/O wait)Waiting for the disk: swapping, logging to a slow disk or the database
High st (steal)The host gives your VPS less CPU than it needs. Not your application; talk to the provider or move
si/so above zero in vmstat, swap in useThe server is swapping. Reduce memory use. Java and swap are a bad mix
Low CPU but the app is slowWaiting: database, remote API, DNS, locks. Go to step 5

2. Is it garbage collection?

sudo -u appuser jstat -gcutil $(pgrep -f myapp.jar) 1000 10

Columns FGC and FGCT are the number and total time of full collections. If they grow every few seconds while O (old generation) stays near 100, the heap is too small or the application leaks memory. Raise the heap if the server has room, or check for a leak with a heap dump. Choose the collector for your size: choose a garbage collector.

3. Find the hot thread

top -H -p $(pgrep -f myapp.jar)          # note the PID of the thread with highest %CPU
printf "%x\n" THREAD_PID                 # convert it to hexadecimal
sudo -u appuser jcmd $(pgrep -f myapp.jar) Thread.print | grep -A 15 "nid=0xHEX"

Replace THREAD_PID and HEX with your values. The stack trace shows where the thread spends time. Take two or three snapshots a few seconds apart. If the same method is on top each time, that is your hot spot. Names starting with GC Thread or G1 mean garbage collection, which sends you back to step 2.

4. Startup spike or JIT

High CPU for the first minute after a start is normal. The JIT compiler works hard while the application warms up. On a one-core server this makes the site slow right after every restart. Plan restarts for quiet times, or add a core.

5. Everything else is waiting

  • Database. Turn on the slow query log (MySQL slow_query_log, PostgreSQL log_min_duration_statement). A missing index is the single most common reason for a slow Java application.
  • Thread pool exhausted. A thread dump shows many threads blocked in the same place, often waiting for a database connection. Look for the pool settings (HikariCP maximumPoolSize).
  • External calls and DNS. Add timeouts to every HTTP client. A slow partner API makes your own threads pile up.
  • Disk. iostat -x 2 shows if the disk is saturated, for example by verbose logging.

6. Keep the evidence

Next time it happens you want numbers. Turn on monitoring and GC logging (-Xlog:gc*:file=/var/log/myapp/gc.log). Graphs of CPU, memory and response time answer most of these questions without guessing.

Questions about java app slow or high cpu

What does CPU steal mean?

The hypervisor gave CPU time to other virtual machines when yours wanted it. Consistent steal above a few percent means the host is oversold.

Last updated October 29, 2026.

Your own Java server, billed monthly

Plans from €15.30 a month. Set up for you, or run for you.