Bir application server neden yavaşlar, nasıl anlarsınız

"Sistem yavaşladı" şikayeti geldiğinde elinizde somut veri olmadan tahmin yürütmek zaman kaybettirir. TROIA application server'ı Java üzerinde çalıştığı için, JVM'i izlemek için TROIA'ya özgü bir araç yerine standart bir Java aracı kullanılıyor: VisualVM. CPU kullanımından bellek sızıntılarına, thread kilitlenmelerinden metod bazlı profiling'e kadar tüm görüntüleme ihtiyacı tek bir araçtan karşılanıyor.

Kurulum ve bağlanma

VisualVM'i https://visualvm.github.io/ adresinden indirip, Windows'ta bin\visualvm.exe ile çalıştırıyorsunuz. etc\visualvm.conf dosyasındaki visualvm_default_options ve visualvm_jdkhome parametreleri, aracın hangi JDK'yı kullanacağını belirliyor — application server'ın çalıştığı JDK sürümüyle uyumsuz bir JDK ile bağlanmaya çalışmak, bazı sekmelerin (özellikle profiling) hiç açılmamasına yol açabilir.

Sol paneldeki yerel JVM'ler listesinden application server'ın process'ine çift tıklayarak bağlanıyorsunuz. Aynı sunucuda birden fazla application server instance'ı çalışıyorsa, Task Manager'dan doğru process ID'yi (PID) doğrulamak karışıklığı önler.

CPU ve bellek izleme: Monitor sekmesi

Bağlandıktan sonra Monitor sekmesi JVM uptime, CPU ve bellek tüketimini grafiksel olarak gösteriyor; thread sayısı ve yüklenen sınıf sayısı da aynı yerden takip edilebiliyor. Burada elle Garbage Collector tetikleyip, kullanılmayan nesnelerin gerçekten temizlenip temizlenmediğini (ve olası bir memory leak olup olmadığını) gözlemleyebilirsiniz.

Heap Dump: "bellekte ne var" sorusunun cevabı

Bir heap dump, o anki heap bellek alanındaki tüm sınıfları ve içeriklerini bir dosyaya döker. "Objects" görünümünde sınıf ya da paket adına göre filtreleme yapılabilir; her nesne için sayı, kapladığı bellek ve alt alanları görülebilir. "Retained size" metriği özellikle önemli — bir nesne silindiğinde, sadece kendisinin değil, ona bağlı referansların da ne kadar belleği serbest bırakacağını gösteriyor; yani bir memory leak ararken hangi nesneyi "temizlemenin" gerçekten işe yarayacağını buradan anlarsınız.

Dikkat: Canlı bir ortamdan alınan heap dump, müşteri verisi (kişisel bilgiler, ürün fiyatları vb.) içerebileceğinden bilgi güvenliği riski taşır — dump dosyasını sunucudan indirmeden önce içeriğinin nereye gideceğine dikkat edin.

Thread Dump: "her thread şu an ne yapıyor"

Bir thread dump, her thread'in o anki durumunu ve call stack bilgisini gösterir. TROIA application server'larında CANIAS(rmi) önekli thread'ler kullanıcı işlemlerini, CANIAS(checker) önekli thread'ler ise kullanıcı oturumlarını izleyen arka plan thread'lerini temsil eder. Bir dialog "takılı" kaldığında, ilgili kullanıcının CANIAS(rmi) thread'inin call stack'ine bakmak, kodun tam olarak hangi satırda beklediğini (örneğin bir veritabanı sorgusunda mı, harici bir web servis çağrısında mı) gösterir.

Sampling: düşük maliyetli ama kaba bir yöntem

CPU ve Memory Sampling, JVM'den belirli aralıklarla veri okuyarak çalışır, bu yüzden sistem üzerinde düşük yük yaratır. Garbage Collector etkisini ve nesne sayılarını izlemek için yeterlidir ama karmaşık, kısa süreli performans sorunlarını yakalamak için yetersiz kalabilir — daha derin bir analiz gerektiğinde profiling'e geçmek gerekir.

Profiling: gerçek darboğazı bulmak

CPU Profiling: Profiling sekmesinde standart kütüphaneleri hariç tutacak paket filtreleri belirleyip CPU butonuna basarsınız, ardından şüpheli işlemi tetiklersiniz. Sonuçta üç kritik metrik görürsünüz: Invocations (kaç kez çağrıldığı), Total Time (toplam CPU süresi) ve Self Time (yalnızca o metodun kendi süresi, alt çağrılar hariç). Bir metod yüksek "Total Time" ama düşük "Self Time" gösteriyorsa, sorun o metodun kendisinde değil çağırdığı bir alt işlemdedir — bu ayrım, "hangi kod satırını optimize etmeliyim" sorusunu doğrudan cevaplar.

Memory Profiling: TROIA için genelde com.ias.** gibi kısıtlayıcı bir paket filtresiyle başlatılır. Amaç, bellek tüketimini optimize etmek ya da olası leak'leri tespit etmektir. Normal koşullarda otomatik tetiklenen Garbage Collector, profiling sırasında nesne sayılarını yanıltıcı şekilde şişirebilir — bu yüzden ölçüm sırasında GC'nin ne zaman çalıştığına dikkat etmek gerekir.

Pratik bir teşhis akışı

  1. Şikayet geldiğinde önce Monitor sekmesinden CPU/bellek grafiğine bakıp genel bir anormallik var mı görün.
  2. CPU sürekli yüksekse CPU Profiling ile hangi metodun "Self Time"ının yüksek olduğunu bulun.
  3. Bellek sürekli artıyor ve GC sonrası düşmüyorsa bir Heap Dump alıp "retained size"a göre sıralayın.
  4. Belirli bir kullanıcı/dialog "takılı" görünüyorsa o oturuma ait CANIAS(rmi) thread'inin Thread Dump'taki call stack'ine bakın.

Sıradaki adım

JMX üzerinden application server'ı programatik olarak izlemek (VisualVM'in GUI'siz, otomasyona uygun karşılığı) bir sonraki yazının konusu.