Spring Boot 2.2 vs 2.3 vs 2.4 (Java 11)

Geçen sene Spring Boot 2.2.0 release notlarında bahsi geçen performans iyileştirmelerini gözlemledikten sonra elde ettiğim bulguları şu yazı ile paylaşmıştım: Spring Boot 2.1 vs 2.2: Bellek Kullanımı ve Başlangıç Süresi İyileşmiş

https://start.spring.io/ üzerinden an itibariyle seçilebilen Spring Boot versiyonlarını Java 11 ile ayrı ayrı VisualVM ile gözlemleyerek, yeni bir Spring Boot projesi oluştururken yapacağımız seçimlerin performansa ve kaynak kullanımına ne gibi etkileri olabileceğini yeniden gözlemlemeye çalıştım.

LTS versiyon olmadığı için Java 15 ile ilgilenmedim; onun yerine Java 17’yi beklemeyi düşünüyorum. Ayrıca önceki yazıda Java 8’den Java 11’e geçişte bariz bir iyileşme sağlandığı için Java 8 ile de ilgilenmedim.

Gelelim sonuçlara:

Spring Boot2.2.122.3.72.4.1
Final “ayrılmış” bellek (heap size)~383 MB~383 MB~383 MB
Final “kullanılan” bellek (used heap)~67 MB~70 MB~237 MB
Maksimum “kullanılan” bellek~248 MB~214 MB~237 MB
Uygulama başlangıç süresi~9.5 sn~9.7 sn~11 sn

Not: Önceki yazı sırasında gözlemleri farklı bir uygulama üzerinde yaptığımdan buradaki değerlerle karşılaştırmak yanlış olur.

2.2.12’den 2.3.7’ye geçerken bir miktar iyileşir gibi olan maksimum “kullanılan” bellek dışında bir iyileşme gözlemleyemedim. İyileşme gözlemleyememek bir yana, 2.4.1’e giderken tablo bir miktar kötüleşiyor hatta…

Bu yazıda geçen yazıdaki gibi dramatik bir sonuç çıkmadı. Zaten her yeni Spring Boot versiyonu da performans / kaynak kullanımı iyileştirmesi vaat etmiyor. Ben yalnızca geçen sürede bir şeyler değişmiş mi gözlemlemek istedim…

“Gözlem” derken?

Bu iki yazıda yaptığım şeyi özellikle “performans testi” yerine basitçe “gözlem” olarak nitelendiriyorum. Performans testi gibi daha fazla değişkenin faklı bakış açılarıyla ele alınacağı, daha ciddi uğraş gerektiren bir çabaya henüz girmedim.

Diğer taraftan, dikkatinizi çekmek istediğim başka bir nokta var: Örneğin farklı “garbage collector” türleri ve farklı JDK dağıtımları arasında karşılaştırmalar yapmak gibi uğraşlara da girilse, uygulamanın gerçek çalışma zamanı metrikleri de elde edilse, en nihayetinde burada ortaya çıkacak değerler uygulama karakteristiğine göre değişecek ve uygulama gereksinimlerine göre farklı yorumlanmak durumunda kalacak. Örneğin bir “batch” uygulamasının “key” performans metriği başlangıç süresi ve bellek kullanımından ziyade belirli bir zaman aralığında kaç kayıt işlediği olabilir. Benzer şekilde, örneğin bir REST API uygulamasının eş zamanlı kaç isteği, ne kadar bellek kullanarak, ve ortalama kaç milisaniyede işleyebildiği o uygulamanın asıl irdelenmesi gereken metrikleri olabilir. Bunlar gibi metrikleri ölçecek ve değerlendirecek yazılarda görüşmek dileğiyle…

Spring Boot 2.1 vs 2.2: Bellek Kullanımı ve Başlangıç Süresi İyileşmiş 🥳

Spring Boot 2.2.0 güncellemeleri arasında dikkatimi en çok performans iyileştirmeleri çekti; hem bellek kullanımı hem de uygulama başlangıç süresinde iyileştirmeler getirildiği söylenmiş:

Ben de Spring Boot 2.1.4 (Java 8) kullanan bir projemizi -tek fark Spring Boot versiyonu olacak şekilde- önce birkaç kere 2.1.4 ile, sonra birkaç kere de 2.2.0 ile ayağa kaldırdım ve uygulamayı VisualVM ile gözlemledim. Uygulama başlangıç zamanı / CPU kullanımı anlamında farkedilebilir bir iyileştirme gözlemleyemedim, diğer taraftan bellek kullanımının bir hayli iyileşmiş olduğunu gördüm:

Spring Boot2.1.42.2.0Fark
Final “ayrılmış” bellek (heap size)~1.6 GB~1 GB-37.5 %
Final “kullanılan” bellek (used heap)~600 MB~240 MB-60.0 %
Maksimum “kullanılan” bellek~630 MB~450 MB-28.5 %
Uygulama başlangıç süresi~75 sn~75 sn0

Bu değerler, ayağa kalkmasının üstünden kısa bir vakit geçmiş, fakat henüz hiçbir istek karşılamamış uygulamalardan alındı. Daha gerçekçi bir test, çalışma zamanı davranışlarını daha uzun vadede incelemeyi gerektirir elbette. Ancak yine de bu gördüklerim beni etkilemeyi başardı…

ÖNEMLİ GÜNCELLEME: Eğer Java 11’e geçerseniz…

Yukarıdaki testi Java 8 ile, sadece Spring Boot versiyonunu değiştirerek gerçekleştirmiştim. Java 11 ile test ettiğimde ise gözlerime inanamadım. Spring Boot 2.2.0 ve Java 11 ikilisiyle, Spring Boot 2.2.0 ve Java 8 ikilisine göre hem bellek kullanımında hem de uygulama başlangıç süresinde yaklaşık yarı yarıya iyileşme sağlandı…

Madem Java 11 ile böyle bir iyileşme sağlandı, belki de Java 8’den sonraki LTS (Long-term support) versiyon olan Java 11’e geçmek için güzel bir bahane bulmuş olabiliriz:

Bootiful günler dilerim 🤓

Biz Bunları Gist’lerimizde Anlattık! – PostgreSQL

Geliştirici olarak bir projeden/işyerinden ayrılırken “bu projeye çok emek verdi(m)(k), bazı kısımlar şahane, lazım olur günün birinde, zipleyeyim de atayım kenarda dursun” hissiyatı çoğumuzda olur. Ben ise şu iki sebeple bunu yapmaya gerek görmüyorum:

  1. Geçmiş deneyimlerimiz ile yeni çevrede öğrenilen yeni bilgileri harmanlayarak daha iyilerini yazabileceğimize inanıyorum
  2. Geçmiş deneyimlerimi unutmamak için blog ve Gist yazıyorum

(Ayrıca projeyi o şekilde başka yerlere kopyalamak yasal olarak da sıkıntılı olsa gerek.)

github-gist

Gist yazmak da blog yazmak gibi, ama ağırlıklı olarak kod parçaları -hatta çoğu zaman dosyalar- içermekte. Bir baktım 2015’ten bu yana Gist karalıyormuşum. Bazıları public, bazıları private, bazıları blog tarzında uzunca (onları buraya taşısam daha iyi olacak), bazıları bir kaç kelime açıklama ardından bir kaç dosyadan oluşmakta. Her gün işim düşmese de 1-2 ayda bir işim düşüyor oradaki notlarıma.

Bu sabah production ortamındaki bir durumu çözmeye çalışırken öğrendiğim bir yöntem için yeni bir Gist yazınca, ben neden Gist yazıyorum diye tekrardan bir düşünüp yazıya dökmek istedim. Gist PostgreSQL üzerineydi. Geriye dönüp bakınca farkettim, 1 yıl içinde PostgreSQL ile alakalı faydalı olduğunu düşündüğüm 5 adet Gist yazmışım. Günün birinde sizlere de faydalı olması dileğiyle, buyrunuz…

ALTER TABLE ve başka pahalı sorguların çok daha hızlı çalışması için:

BEGIN;
LOCK TABLE … IN SHARE MODE;
SET LOCAL WORK_MEM = '256MB';
ALTER TABLE …;
COMMIT;

Tabloyu kilitlemeden INDEX ekleyip çıkarmak için:

CREATE INDEX CONCURRENTLY your_index_name on your_table_name (your_column_name);
DROP INDEX CONCURRENTLY your_index_name;

“Biz Bunları Gist’lerimizde Anlattık! – PostgreSQL” yazısını okumaya devam et