Bir çoğumuz Java uygulamalarımıza memory ataması yaparken minimum ve maksimum heap size değerlerini verir ve öyle çalıştırırız. Çoğu kez sorun yaşamasak da uygulamada oluşabilecek memory problemlerinin tespiti ve yoğun uygulamalarımızın daha efektif çalışması için garbage collection loglamasını enable etme ve ek garbage collection parametrelerini set etme ihtiyacı duyarız. Bu noktada sizlere Jrockit'in bazı memory parametreleri ve garbage collection işlemleri hakkında bilgi vermeye çalışacağız.
Bir JVM i start ederken en temel şekilde aşağıdaki parametreleri veririz:
Xms: JVM
in başlarken alacağı minimum memory değerini belirtir.
ör: -Xms8G
-Xmx: JVM devam ettiği sırada alacağı maksimum
memory değerini belirtir.
ör: -Xmx16G
Şimdi biraz yaşayabileceğimiz memory problemlerimiz sonrasında elimizde incelemek üzere nasıl data oluşturacağımza bakalım. Aşağıdaki parametreler Weblogic managed serverların start up parametrelerine eklenerek istenen çıktılar elde edilebilir:
-XX:+|-CrashOnOutOfMemoryError: Out of memory durumunda port ayakta kalır, ancak
uygulama cevap vermez. Bu seçenek etkinleştirildiğinde ’out of memory’ hatası olması durumunda JVM down durumuna geçer.
ör: -XX:+CrashOnOutOfMemoryError
-XX:+|-HeapDiagnosticsOnOutOfMemoryError: Bu seçenek
etkinleştirildiğinde, ‘out of memory’ hatası olması durumunda heap in o anki
durumunu belirtir bir rapor üretilir. Bu rapor dosyası - XX:HeapDiagnosticsPath
seçeneği ile belirlenen dizine yazılır.
ör: -XX:+HeapDiagnosticsOnOutOfMemoryError -XX:HeapDiagnosticsPath=D:\myapp\diag_dumps
-XX:+|-HeapDumpOnOutOfMemoryError:
Bu seçenek ile out of memory hatası durumunda heap dump oluşturulur. Sonrasında
bu oluşturulan heap dump dosyası Eclipse Memory Analyzer ya da benzeri bir tool
ile incelenerek olası memory problemleri tespit edilmeye çalışılır.
ör: -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath: -XX:+|-HeapDumpOnOutOfMemoryError seçeneği etkinleştirildiğinde oluşturulacak heap dump ın dizinini ve dosya ismini belirlenir.
ör: -XX:+HeapDumpOnOutOfMemory -XX:HeapDumpPath=D:\myApp\hprof-dumps
-XXtlaSize: Muti-thread
çalışan uygulamalarda thread başında memory ayarlaması amacıyla kullanılır.
TLA, Java uygulamasının kullandığı objelerin boyutuna veya fazlalığına göre
ayarlanmalıdır. Parametrelere eklenecek değerler şu şekildedir.
min= TLA minimum değeri
preferred=TLA tercih edilen değeri
wasteLimit=Bir TLA’nın izin verilen en büyük memory değeri
ör: -XXtlasize:min=2k,preferred=16k
Garbage Collection:
JVM e min ve max heap size
değelerini set edip start ettiğimizde sistemden belirtilen memory değerini sistemin fiziksel memory sinden allocate eder ve uygulamaya verir. Bu noktadan sonra uygulama JVM'e ayrılmış bu miktardan sürekli
olarak memory alır ve işini yürütmeye devam eder. Uygulama çalışmaya devam
ettikçe yeni aldığı memory çöp haline gelir ve artık kullanılamaz durumdadır.
Bu nedenle sürekli yeni memory ihtiyacı hisseder. Oysa biz memory i max heap
size değeri ile sınırlamıştık. Dolayısıyla uygulama tarafından kullanılan ve çöp
haline gelen bu memory nin bir şekilde bir geri dönüşüm işlemine sokulması
gerekmektedir. İşte bu geri dönüşüm işlemine Garbage Collection denmektedir.
Heap üzerinde bir GC işlemi başladığında aşağıdaki şekilde görünen heap in tamamı taranarak o an kullanılmayan (referans gösterilmemiş) objeler belirlenir ve ikinci şekildeki gibi (After Marking) heap haritası çıkarılmış olur. Bu noktadan sonra temizleme işlemi başlar ve free memory oluşturularak uygulamanın yeniden kullanımına hazır hale getirilmiş olur.
Yukarıda bir GC işlemini kabaca anlatmaya çalıştık.Şimdi biraz daha detaya inelim. GC'nin iki farklı tipi vardır.
Young Garbage Collection :
Young generation üç hafıza alanından oluşmaktadır. Bunlar
Eden, Survivor 1 ve Survivor 2 hafıza alanlarıdır. Bir JVM start olup uygulamayı available hale getirdiğinde objelerin hepsi Eden space'de oluşur. Survivor 1 ve
Survivor 2 alanları ise geçici ara bellek alanlarıdır. Eden hafıza
alanı dolduğunda, Garbage Collector live objeleri önce boş olan
Survivor alanlarından birisine kopyalar. Bu işlemin ardından Garbage Collector
Eden ve kullanımda olan Survivor alanını boşaltır. Eden hafıza alanı tekrar
dolduğunda, live objeler ve dolu olan Survivor alanındaki nesnelerin
hepsi tekrar boş olan Survivor alanına kopyalanır. Her zaman bir Survivor alanı
boştur ve bir sonraki Young Garbage Collection işlemi sonunda live objeleri bünyesine alacak şekilde pasif olarak bekler..
Old Garbage Collection :
Young GC işlemlerinin yeterli olmadığı durumlarda Old GC
devreye girer. Bu işlem sırasında o sırada JVM üzerinde aktif olarak çalışan
tüm thread ler durdurularak temizleme işlemi başlatılır ve işlem bitince tüm
thread ler kaldıkları yerden devam ederler. Temizlenecek heap ne kadar büyükse
(max heap size) Old GC (Full GC) de bir o kadar uzun sürecektir. Dolayısıyla
uygulamamız için optimum max heap size değerini bulmamızda fayda var. GC süresi
ne kadar uzunsa kullanıcılar bu işlem sırasında o kadar fazla bekleyeceklerdir.
(donma)
Aşağıdaki grafik
Young ve Full GC işlemlerini göstermektedir. Görüldüğü üzere testereye benzeyen
şekilde ayrıca küçük merdivenler de bulunmaktadur. İşte her bir testere
dişindeki ufak merdiven basamaklarını andıran bu işlemler Young GC işlemlerini
göstermektedir. Her bir testere dişi de Full GC işlemlerini temsil eder. Biraz
daha açıklamak gerekirse JVM start edildikten sonra belli aralıklarla Full GC
işlemlerine tabi tutulmuş, her Full Gc sonrası memory kullanımı 500 MB
seviyelerinden 250 MB seviyelerine inmiştir. Testere dişlerinin en dip
noktalarını biz çizgi ile birleşirdiğimizde doğruya yakın bir şekil oluşmasını
bekleriz. Eğer yukarıya doğru eğilmi bir doğru oluşuyorsa bu, uygulamamızda bir
memory leak olduğunu gösterir. Bu tip
bir durumd belli bir süre sonra Full GC işlemleri sonrası free memory miktarı
daha yüksek seviyelerde kalacak ve bir müddet sonra Full Gc işlemi anlamsız
olacak, sonuç olarak da JVM Out Of Memory hatası alarak duracaktır.
Garbage Collection işleminden bahsettikten sonra Jrockit'in GC parametreleri hakkında bilgi verebiliriz. Bu açıklamalar ışığında sizler de uygulamanıza en uygun GC algoritmasını seçip performans tuning işlemlerinizi yapabilirsiniz. Ancak daha önce belirttiğimiz gibi uygulamanız inanılmaz derecede memory kullanmıyorsa Jrockit'e sadece min ve max heap size değerlerini vermeniz bile yeterli olabilir. Deneyip kontrol etmenizde fayda var.
Jrockit GC Parametreleri
-Xgcprio:pausetime : GC sırasında uzun duraksamalar istemiyorsak bu parametreyi
kullanabiliriz. Paralel GC işleminden biraz daha fazla kaynak (cpu ve memory)
tüketimine neden olur.
ör: -Xgcprio:pausetime -XpauseTarget:250 (-XpauseTarget
parametresi verilmezse default 200 ms kabul edilir)
-XgcPrio:throughput: Uygulamanın optimum throughput sağlaması için bu seçenek
kullanılır. Bu seçenek kullanıldığında Full GC sırasında belirlenemeyen uzun süreli
stop time lar oluşabilir. Ancak yine de GC işlemi olabildiğince optimum çalışır
ve JVM thread lere verebildiği kadar cpu kaynağı verir. Default değer budur.
ör: -XgcPrio:throughput
-XgcPrio:deterministic:Çok kısa ve öngörülen stop time lar için
bu parametre kullanılır. Verilen pause time’dan daha kısa sürede GC işlemleri
bitirilmeye çalışılır.
-Xgc:genpar Genel GC tipidir. Objeler önce Young
Generation space de toplanır. Nursey size (Young Generation Space) full
olduğunda Jrockit, JVM in tüm thread lerini durdurur ve paralel Nursery GC
işlemini başlatır. Bu sırada uygun durumda olan tüm CPU kaynakları kullanılarak
live durumda olan tüm objeler YG space den Old Generation space e taşınır. Bütün
heap dolduğunda ise Old GC collector tüm thread leri durdurarak Full GC
işlemini başlatır.
-Xgc:gencon Bu algoritmada genel ve eş zamanlı bir GC
işlemi yapılır. Objeler Nursery size’da toplanır. Nursery size dolduğunda tüm
JVM thread ler durdurulur ve tüm live objeler Old Generation Space e taşınır ve
Full GC işlemi yapılr.
-Xns: Uygulamamız
çok fazla geçici obje oluşturuyorsa, bu parametreyi yüksek vermemizde fayda
vardır.
ör: -Xns:1G
Default
Nursery Size
|
|
|
|
|
|
sanal işlemci başına 10 MB
|
|
|
|
sanal işlemci başına 10 MB
|
|
|
-XXgcThreads: Full GC
yapılırken aynı anda kaç thread ile JVM in temizleneceğini belirtir. Bu
parametre kullanıldığında CPU tüketimi artar ancak GC süresi azalır. Cpu
bakımından güçlü serverlarda bu parametre kullanılabilir.
ör: -XXgcThreads:4
GC Loglamasının Enable Edilmesi:
-Xverbose: JVM output u hakkında bilgi verir.
ör:-Xverbose:memory
-Xverboselog: GC loglarının (JVM out put) dizininin ve log isminin tanımlanmasını sağlar.
ör: -Xgc:genpar -Xverboselog:/log/dizini/logname_gc.log -Xverbose:memory
Yukarıdaki parametrelerin eklenmesinin ardından JVM restart edilirse; GC loglaması enable duruma getirilmiş olur. Aşağıda örnek GC logları görülebilir.