Belajar Spring Boot - Performance & JVM Optimizations
Episode 16 of 24

Belajar Spring Boot - Performance & JVM Optimizations

Episode ini membahas penyempurnaan performa: profiling dengan JFR dan async-profiler, tuning heap dan JVM flags dengan GC G1 dan ZGC, optimasi startup time dan memory footprint, serta tuning cache dan connection pool.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Aplikasi yang lambat jarang butuh teknologi baru — biasanya butuh menemukan di mana waktu hilang. Episode 16 membahas performance dan JVM optimizations: cara mengukur, menemukan hambatan, lalu mengoptimalkan aplikasi Spring Boot dengan pengetahuan yang benar.

Kalian akan belajar memakai JFR dan async-profiler untuk profiling, mengatur JVM flags dan memilih garbage collector, mempercepat startup, serta mengecilkan memory footprint dan mengatur koneksi dengan tepat.

Profiling Aplikasi dengan JFR dan async-profiler

JFR: Java Flight Recorder

JFR adalah profiler bawaan JVM yang mencatat event runtime — alokasi memory, GC, thread, dan metode yang panas — dengan overhead sangat rendah. Rekam sesi saat aplikasi berjalan:

Rekam JFR selama 60 detik
jcmd 1234 JFR.start name=profil duration=60s \
  filename=profil.jfr

jcmd 1234 JFR.start name=profil duration=60s filename=profil.jfr merekam profiling selama 60 detik ke file profil.jfr. Buka file tersebut di JDK Mission Control untuk menganalisis metode mana yang memakan waktu dan memory.

async-profiler

async-profiler mengukur CPU dan alloc secara sampling tanpa stopping threads. Satu command bisa menghasilkan flame graph:

Ambil CPU flame graph
./async-profiler -d 60 -o flamegraph -f flamegraph.html <pid>

Perintah ./async-profiler -d 60 -o flamegraph -f flamegraph.html <pid> mengambil sampel selama 60 detik dan menghasilkan flame graph interaktif. Dari sini kalian langsung melihat jalur pemanggilan yang paling mahal.

Tuning Heap dan JVM Flags

Mengatur Heap dengan Benar

Salah satu keputusan paling umum: berapa heap yang diberikan. JVM default menentukan heap sebagai persentase dari total memory, tapi untuk container sebaiknya diatur eksplisit:

JVM flags untuk heap
java -Xms512m -Xmx1024m \
  -XX:MaxMetaspaceSize=256m \
  -jar target/belajar-spring-boot.jar

-Xms menetapkan ukuran awal heap, -Xmx ukuran maksimal, dan -XX:MaxMetaspaceSize membatasi metaspace. Jangan memberi heap lebih besar dari memory container — JVM bisa kehabisan memory karena GC dan metaspace.

GC Modern: G1 dan ZGC

Java 21 mendukung dua garbage collector modern:

  • G1 — default sejak Java 9; menyeimbangkan throughput dan latency dengan region-based collection.
  • ZGC — low-latency; pause mikro bahkan untuk heap sangat besar, cocok untuk aplikasi dengan SLAM ketat.
Memakai GC ZGC
java -XX:+UseZGC -jar target/belajar-spring-boot.jar

Sebelum mengganti GC, ukur dulu profil aplikasi kalian. ZGC unggul untuk latency, G1 lebih efisien untuk throughput umum. Keputusan harus berdasarkan data profiling, bukan tren.

Optimasi Startup Time dan Memory Footprint

Lazy Initialization

Spring Boot memulai banyak bean saat startup. Lazy initialization menunda pembuatan bean sampai pertama kali dipakai, mempercepat startup dengan mengorbankan sedikit latency request pertama:

Aktifkan lazy initialization
spring:
  main:
    lazy-initialization: true

Teknik ini berguna untuk aplikasi yang butuh startup cepat — misalnya fungsi serverless atau auto-scaling — tapi pikirkan konsekuensinya: error konfigurasi baru muncul saat bean dipakai, bukan saat startup.

Mengurangi Konsumsi Memory

Beberapa langkah untuk memory footprint yang lebih kecil:

  • Gunakan -Xmx sesuai kebutuhan nyata, bukan setinggi mungkin.
  • Batasi ukuran thread pool dan connection pool sesuai kapasitas.
  • Hindari menyimpan object besar di cache tanpa batas.
  • Pertimbangkan native image (episode 20) untuk startup dan memori yang jauh lebih kecil.

Persistent Context, Cache, dan Connection Pool Tuning

Caching dengan Spring Cache

Cache mengurangi beban database dengan menyimpan hasil pemanggilan yang sering berulang. Aktifkan @EnableCaching dan tandai method yang perlu di-cache:

Caching method
@Service
public class ItemService {
 
    @Cacheable("items")
    public Item findById(Long id) {
        return repository.findById(id)
                .orElseThrow(() -> new ItemNotFoundException(id));
    }
}

Cache items menyimpan hasil findById sehingga panggilan berikutnya tidak menyentuh database. Tambahkan provider seperti Caffeine untuk cache in-memory yang cepat, dan gunakan @CacheEvict untuk mengosongkan cache saat data berubah.

Tuning Connection Pool HikariCP

HikariCP adalah connection pool default Spring Boot. Atur ukurannya sesuai kebutuhan — bukan sebanyak mungkin:

Konfigurasi HikariCP
spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000
      max-lifetime: 1800000

maximum-pool-size menetapkan jumlah koneksi maksimal, connection-timeout waktu tunggu mendapatkan koneksi, dan max-lifetime umur maksimal koneksi. Ukuran pool yang terlalu besar justru membuang resource database.

Penutup

Episode 16 membekali kalian dengan penyempurnaan performa: profiling dengan JFR dan async-profiler, tuning heap dan JVM flags dengan GC G1 atau ZGC, optimasi startup dan memory footprint, serta tuning cache dan connection pool.

Inti yang harus dibawa pulang:

  • Ukur dulu dengan JFR atau async-profiler sebelum mengoptimalkan apa pun.
  • -Xmx harus disesuaikan dengan memory container, jangan terlalu besar.
  • G1 untuk throughput umum; ZGC untuk latency rendah.
  • Lazy initialization mempercepat startup dengan mengorbankan request pertama.
  • Spring Cache dengan @Cacheable mengurangi beban database.
  • Ukuran connection pool HikariCP disesuaikan dengan kapasitas, bukan dimaksimalkan.

Di episode 17 selanjutnya kita akan membahas testing dan quality assurance — unit testing dengan JUnit 5 dan Mockito, integration testing dengan @SpringBootTest dan @WebMvcTest, contract testing dengan Spring Cloud Contract, serta Testcontainers untuk database dan dependency.

Belajar Spring Boot - Performance & JVM Optimizations | Belajar Spring Boot