Java uygulaması nasıl profillenir ve hızlandırılır: ölçüm yöntemi
Beceri rehberi

Java uygulaması nasıl profillenir ve hızlandırılır: ölçüm yöntemi

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Java uygulamasını JFR ve thread dump ile profilleme, darboğaz kalıplarını tanıma, JIT ısınmasına dikkat ve ölçerek iyileştirme yöntemi.

Performans analizi tahmin değil, ölçüm işidir

"Uygulama yavaş" şikâyeti gelir ve ekip ilk iş olarak şüpheli gördüğü koda dokunur. Çoğu zaman yanlış yere optimizasyon yapılır: yavaşlık sorgudadır, kod değil; ya da bekleme kilit çekişmesindendir, işlemci değil. Profilleme, vakti nerede harcadığınızı varsayım yerine kanıtla gösterir.

Java'da sağlıklı bir analiz akışı şudur: önce belirtiyi tanımlayın (yüksek gecikme mi, düşük verim mi, yüksek işlemci mi, bellek baskısı mı). Sonra üretime olabildiğince yakın bir yükte ölçüm alın. Ölçüm sonucuna göre bir hipotez kurun, tek bir değişiklik yapın ve aynı ölçümü tekrarlayın. İyileşme ölçülmediyse iyileşme yoktur.

Doğru aracı seçmek: JFR, thread dump ve harici profilleyiciler

JDK, ek kurulum gerektirmeden kullanabileceğiniz bir kayıt aracıyla gelir: Java Flight Recorder (JFR). Düşük maliyetli bir olay kayıt çerçevesidir; JVM'den, işletim sisteminden ve uygulamadan olayları toplar. Üretimde kullanılabilecek kadar hafif tasarlanmıştır.

JVM başlatılırken kaydı açmak için:

java -XX:StartFlightRecording=duration=<süre>,filename=kayit.jfr,settings=profile -jar uygulama.jar

Çalışan bir süreçte ise önce süreç kimliğini bulun (jcmd ya da jps -l), sonra kaydı başlatın:

jcmd <pid> JFR.start name=kayit settings=profile duration=<süre> filename=kayit.jfr

Kayıt sürerken anlık görüntü almak, durdurmak ve etkin kayıtları listelemek için JFR.dump, JFR.stop ve JFR.check komutları vardır. settings=profile, varsayılandan daha ayrıntılı ama biraz daha pahalı olay toplar; analiz penceresinde yararlıdır. Kaydı JDK Mission Control ile açıp otomatik analizi, olay tarayıcısını ve bellek, iş parçacığı, G/Ç ve çöp toplama görünümlerini kullanabilirsiniz.

Kısa ve hızlı bir bakış için thread dump yeterlidir: jcmd <pid> Thread.print. Birkaç saniye arayla alınan dökümler, iş parçacıklarının sürekli aynı yerde beklediğini gösteriyorsa darboğaz oradadır. Harici örnekleyici profilleyiciler de yaygındır; hangisini seçerseniz seçin amaç, çağrı yığınlarını örnekleyip alev grafiği gibi bir görünümle sıcak noktaları göstermektir.

Adım adım: yavaş bir uç nokta için profilleme akışı

Örnek bir senaryo (kurgusal): Bir sipariş listeleme uç noktası yük altında yavaşlıyor. Ekip şu akışı izler.

Yükü yeniden üretin. Gerçeğe yakın veriyle ve eşzamanlı isteklerle yük testi çalıştırın. Düşük hacimli veriyle yapılan test, gerçek darboğazı gizler.

Kaydı başlatın. Yük sürerken JFR kaydını açın; kayıt yük penceresini kapsasın.

Zaman dağılımına bakın. Mission Control'de en çok işlemci harcayan metotlara ve çağrı yığınlarına bakın. Beklenti kodda değilse (örneğin zaman çoğunlukla veritabanı sürücüsünde bekleniyorsa) sorun uygulama koduna değil veri erişimine aittir.

Bekleme olaylarını inceleyin. İş parçacığı park etme, kilit çekişmesi ve G/Ç bekleme olaylarını kontrol edin. İşlemci boşta ama yanıt yavaşsa, vakit çoğunlukla beklemede geçiyordur.

Ayırma baskısına bakın. Çok sayıda kısa ömürlü nesne oluşuyorsa çöp toplama yükü artar. Bellek olayları hangi kod yolunun bu nesneleri ürettiğini gösterir.

Tek bir iyileştirme yapın ve aynı yükle tekrarlayın. Önce-sonra kıyası olmayan değişiklik performans çalışması sayılmaz.

Sık rastlanan darboğaz kalıpları ve çözümleri

Profil kayıtlarında Java uygulamalarında tekrar tekrar görülen kalıplar: • Her satır için ayrı sorgu (N+1 sorgu): Bir listeyi çekip her satır için ayrı sorgu atmak. Çağrı yığını veritabanı sürücüsünde yoğunlaşır. Çözüm, ilişkili veriyi tek sorguyla getirmek ya da toplu yükleme kullanmaktır • Kilit çekişmesi: Çok iş parçacığının aynı synchronized bloğunda ya da paylaşılan kaynakta beklemesi. Çözüm kritik bölgeyi küçültmek, kilidi bölmek ya da eşzamanlı veri yapılarına geçmektir • Gereksiz nesne üretimi: Döngü içinde sürekli string birleştirme, otomatik kutulama (primitive türleri sarmalayan nesneler), tekrar tekrar derlenen düzenli ifadeler. Çözüm nesneleri yeniden kullanmak ya da yapıyı değiştirmektir • Kontrolsüz önbellek: Boyut sınırı olmayan harita büyüdükçe bellek ve çöp toplama baskısı artar. Çözüm sınırlı ve sona erme politikalı bir önbellektir • Pahalı günlükleme: Günlük düzeyi kapalı olsa bile mesajı önceden oluşturmak maliyetlidir. Çözüm parametreli günlük çağrılarıdır • Bloklayıcı çağrılar: İş parçacığı havuzunu ağ veya disk beklemesiyle doldurmak. Çözüm havuzu bu işlere göre ayırmak ya da zaman aşımı koymaktır

Her kalıbın teşhisi farklı bir olayda görünür: sorgu sayısı sürücü yığınında, kilit çekişmesi kilit olaylarında, nesne üretimi bellek ayırma olaylarında.

Mikro ölçüm ve JIT: sonuçlara güvenmek için dikkat edilecekler

Java'da kod ilk çalıştığında yorumlanır; sık çalışan bölümler JIT derleyici tarafından derlenip optimize edilir. Bu yüzden bir metodu birkaç kez çalıştırıp süreyi ölçmek yanıltıcıdır: ilk çalıştırmalar ısınma dönemidir. Mikro ölçümler için JMH gibi, ısınma ve yinelemeleri doğru yöneten bir araç kullanın. Basit bir sayaçla yazılan karşılaştırmalar, derleyicinin ölü kodu atması gibi etkilere kurban gider.

Üretim profilinde de aynı dikkat geçerlidir: uygulamayı yeni başlattıysanız JIT henüz ısınmamıştır, ölçümü ısınma sonrasında alın. Yük testi ortamı üretimle işlemci, bellek ve veri hacmi açısından uyumsuzsa sonuçlar taşınamaz.

Örnekleme profilleyicilerin bir sınırı da vardır: yalnızca güvenli noktalarda örnek alan araçlar sapma üretebilir. Sonuç beklentinizle uyuşmuyorsa ikinci bir yöntemle (thread dump, farklı araç) doğrulayın.

Sık yapılan hatalar

  • Ölçüm yapmadan "bence şurası yavaş" diyerek optimizasyon yapmak
  • Geliştirici makinesindeki küçük veriyle profil almak
  • Aynı anda birçok değişiklik yapıp hangisinin etkili olduğunu bilmemek
  • Ortalama gecikmeye bakıp yavaş istekleri kaçırmak; gecikme dağılımına bakılmalı
  • Çöp toplama sorununu kodda aramak ya da kod sorununu GC ayarıyla örtmek
  • Üretimde ağır profilleme açıp sistemi yavaşlatmak; düşük maliyetli kayıt (JFR) tercih edilmeli
  • İyileştirmenin işe yaradığını ölçtükten sonra regresyonu yakalayacak sürekli ölçüm koymamak

Performans çalışmasının çıktısı yalnızca bir düzeltme değil, bir kayıt olmalıdır: neyi ölçtük, ne bulduk, ne değiştirdik, sonuç ne oldu.

Bu beceriyi Mindset programlarında nerede çalışırsınız?

Java uygulama profillemesi; yüksek trafikli servisleri işleten backend mühendisleri, performans ve güvenilirlik ekipleri ile üretimde yavaşlık şikâyetine bakan geliştiriciler için gündelik beceridir. Çözülen sorun, darboğazı tahminle değil kanıtla bulmaktır.

Java İleri Seviye: JVM Performans ve Bellek Yönetimi eğitiminde profilleme ve gözlemlenebilirlik, JIT derleme ve kod optimizasyonu ile eşzamanlılık ve kilit analizi ayrı modüllerdir. Bu sıra, bir ekibin kendi servisi üzerinde ölçümden kök nedene gitmesini sağlayan bir çalışma akışıdır.

İlgili Mindset programı

Java İleri Seviye: JVM Performans ve Bellek Yönetimi

Sık sorulanlar

Sık sorulan sorular

Üretimde profil almak güvenli mi?

Düşük maliyetli kayıt araçlarıyla genellikle güvenlidir; JFR üretimde kullanılabilecek şekilde tasarlanmıştır. Yine de ayrıntılı ayarlar (settings=profile) biraz daha maliyetlidir. Önce kısa bir pencerede ve trafiğin düşük olduğu bir anda deneyin, sistem davranışını izleyin, ardından kapsamı genişletin.

JFR ile çalışmak için ek lisans veya kurulum gerekir mi?

JFR, JDK ile birlikte gelir; kayıt başlatmak için ek kurulum gerekmez. Kaydı görselleştirmek için kullanılan JDK Mission Control ise ayrı dağıtılır. Kayıt dosyasını farklı bir araçla ya da komut satırıyla da okuyabilirsiniz. Kullandığınız dağıtımın lisans koşullarını kendi kurumunuz için ayrıca kontrol edin.

Performans sorunu işlemci mi, bekleme mi nasıl anlarım?

Uygulama yavaşken işlemci kullanımı yüksekse zaman işlemde harcanıyordur; sıcak metotları arayın. İşlemci boşta ama istekler yavaşsa iş parçacıkları bir kaynağı bekliyordur: veritabanı, ağ, kilit ya da havuzdaki iş parçacığı sayısı. Thread dump ve JFR bekleme olayları bunu ayırt eder.

Her yavaşlık için profilleme gerekir mi?

Gerekmez. Gecikme tek bir bağımlılıktan geliyorsa dağıtık izleme ve metrikler yeterli ipucu verir. Profilleme, bir servisin içindeki zaman dağılımını görmek gerektiğinde devreye girer. Önce metrik ve izlerle sorunun hangi serviste ve hangi çağrıda olduğunu daraltın, sonra o servisi profilleyin.

Java Performans Analizi: Profilleme Adımları