Ana Sayfa/Java & Kurumsal Mimari
Java & Kurumsal Mimari·31 Ekim 2026·7 dk okuma

JDK 27’de Evrensel G1 GC (JEP 523) ve TLAB İyileştirmeleri, Modern Java Güvenli Kodlama İlkeleri ve Spring Boot’ta jOOQ ‘MULTISET’ Mimarisi

Oracle HotSpot GC ekibinden Thomas Schatzl’ın paylaştığı JDK 27 G1/Parallel/Serial çöp toplayıcı değişiklikleri (JEP 523, Min/MaxHeapFreeRatio 0/100 ve JDK-8381834 TLAB optimizasyonu), SecurityManager sonrası güncellenen Java Secure Coding Guidelines ve Spring Boot’ta jOOQ MULTISET ile tip güvenli SQL projeksiyonları inceleniyor.

JDK 27’de Evrensel G1 GC (JEP 523) ve TLAB İyileştirmeleri, Modern Java Güvenli Kodlama İlkeleri ve Spring Boot’ta jOOQ ‘MULTISET’ Mimarisi

1. JDK 27 G1, Parallel ve Serial GC Değişiklikleri: JEP 523, Yığın Oranları ve TLAB Optimizasyonu

Oracle HotSpot Çöp Toplama (Garbage Collection - GC) ekibi üyesi Thomas Schatzl, Inside.java üzerinden yayımladığı "JDK 27 G1/Parallel/Serial GC changes" raporunda OpenJDK'nın duraklatmalı (stop-the-world) çöp toplayıcılarında gerçekleştirilen yaklaşık 350 mühendislik iyileştirmesini ve mimari sadeleştirmeyi detaylandırdı. JDK 27 ile birlikte özellikle konteyner tabanlı mikroservislerin bellek davranışını doğrudan etkileyen üç temel değişiklik öne çıkıyor:

A. JEP 523 ile G1 Her Ortamda Evrensel Varsayılan Çöp Toplayıcı

Önceki JDK sürümlerinde JVM, düşük işlemci çekirdeği veya küçük bellek sınırı tanımlanmış konteyner ortamlarında (örneğin 1 vCPU ve <2 GB RAM) otomatik olarak Serial GC'ye geri dönüyordu (fallback). Yıllar içinde G1'in yerel bellek ayak izinde (native memory footprint), bariyer senkronizasyonunda ve iş hacminde (throughput) yapılan optimizasyonlar sonucunda JEP 523 devreye alındı. Artık donanım veya konteyner boyutu ne olursa olsun G1 tüm dağıtım ortamlarında koşulsuz varsayılan GC olarak çalışıyor.

B. -XX:MinHeapFreeRatio ve -XX:MaxHeapFreeRatio Değerlerinin 0 ve 100 Yapılması

G1 çöp toplayıcısında uzun yıllardır sırasıyla 40 ve 70 olarak gelen -XX:MinHeapFreeRatio ve -XX:MaxHeapFreeRatio varsayılanları, JDK 27'de 0 ve 100 olarak değiştirildi:

  • Eski Davranışın Sorunu: Uygulama System.gc() çağırdığında veya bir Full GC gerçekleştiğinde, boş yığın oranı %70'in üzerindeyse G1 yığını agresif biçimde küçültüyor, %40'ın altındaysa genişletiyordu. Bu durum üretim ortamlarında gereksiz yığın yeniden boyutlandırma fırtınalarına (heap resizing storms) ve işletim sistemi sayfası (OS page) dalgalanmalarına yol açıyordu.
  • Yeni Davranış: Sabit yüzde eşikleri devre dışı bırakılarak yığın boyutlandırması tamamen GC/uygulama CPU süresi oranı (GCTimeRatio) gibi akıcı sezgisel (heuristic) metriklere devredildi.

C. Kısa Ömürlü İş Parçacıkları İçin TLAB Boyutlandırması (JDK-8381834) ve Atomic<T> Geçişi

Çok sayıda kısa ömürlü ve az bellek ayıran iş parçacığı (short-lived, lightly-allocating threads) oluşturan uygulamalarda TLAB (Thread-Local Allocation Buffer) boyutlandırma algoritması güncellendi (JDK-8381834). Yeni algoritma, TLAB tamponlarının aşırı büyük ayrılmasını önleyerek genç nesil (young generation) bellek israfını ve erken GC tetiklenmelerini ortadan kaldırıyor. Ayrıca HotSpot C++ çekirdeğinde iş parçacıkları arası paylaşılan değişkenler geleneksel volatile + AtomicAccess kalıbından tip güvenli Atomic<T> sarmalayıcılarına taşındı.

[!IMPORTANT]
Konteyner Dağıtım Etkisi: Kubernetes üzerinde küçük CPU/RAM limitleriyle çalışan Java servislerinde JEP 523 sayesinde beklenmedik Serial GC duraklamaları sona ermekte; MinHeapFreeRatio=0 / MaxHeapFreeRatio=100 güncellemesiyle de Full GC sonrası ani RSS bellek dalgalanmaları engellenmektedir.


2. Modern Java ‘Secure Coding Guidelines’ Güncellemesi: SecurityManager Sonrası Savunma Mimarisi

Inside.java tarafından yayımlanan güncel Java Secure Coding Guidelines (Java SE Güvenli Kodlama İlkeleri) incelemesi, Java 17'de kullanımdan kaldırılan (deprecated) ve Java 24'te kalıcı olarak devre dışı bırakılan SecurityManager sonrasında güvenli yazılım mimarisinin nasıl kurgulanması gerektiğini ortaya koyuyor.

Güncel kılavuz, JVM içi çalışma zamanı kum havuzu (sandbox) yerine işletim sistemi/konteyner izolasyonu, JPMS modül sınırları ve veri odaklı doğrulama üzerine odaklanıyor:

mermaid
flowchart LR
    A["Güvenilmeyen Dış Girdi<br/>(Byte Akışı / XML / JSON / API)"] --> B["1. Sınır & DoS Koruması<br/>(Math.addExact, Boyut ve Derinlik Limiti)"]
    B --> C["2. JEP 415 Serileştirme Filtresi<br/>(ObjectInputFilter Beyaz Liste Doğrulaması)"]
    C --> D["3. Değişmez Veri & TOCTOU Koruması<br/>(Java Record, List.copyOf ve Savunmacı Kopyalama)"]
    D --> E["4. Tip Güvenli Veritabanı Katmanı<br/>(Spring Boot + jOOQ MULTISET Derleme Zamanı SQL)"]
  1. Güvenilmeyen Deserialization ve JEP 415 Filtreleri: Java serileştirmesi en yüksek riskli saldırı vektörü olmaya devam ediyor. Kılavuz, ikili (binary) serileştirme yerine JSON/Protobuf gibi yapılandırılmış formatları; yerel serileştirme zorunluysa JEP 415 bağlama özgü ObjectInputFilter beyaz listelerini (maxdepth, maxInputSize, maxarray) zorunlu tutuyor.
  2. Değişmezlik (Immutability) ve TOCTOU Koruması: Doğrulama zamanı ile kullanım zamanı arasındaki (Time-of-Check to Time-of-Use - TOCTOU) yarış durumu zafiyetlerini önlemek için değiştirilebilir (mutable) girdi ve çıktıların List.copyOf() ile savunmacı biçimde kopyalanması ve veri taşıyıcıların değişmez Java record tipleriyle modellenmesi gerekiyor.
  3. Hizmet Reddi (DoS) ve Tamsayı Taşması Koruması: Zip Bomb, XML varlık genişlemesi (XXE) ve bellek ayırma hesaplamalarındaki tamsayı taşmalarına (integer overflow) karşı Math.addExact() ve Math.multiplyExact() kontrolleri standartlaştırılıyor.

3. Spring Boot’ta jOOQ ve Tip Güvenli SQL: Lukas Eder ile ‘Data Geekery’ Analizi

Spring resmi blogunda (Spring.io) Josh Long'un sunduğu A Bootiful Podcast programına konuk olan jOOQ yaratıcısı Lukas Eder, modern kurumsal Java uygulamalarında ilişkisel veritabanlarıyla (PostgreSQL, DuckDB, ClickHouse, CockroachDB) çalışırken karşılaşılan mimari darboğazları değerlendirdi.

Oturumda öne çıkan en kritik mühendislik tezi, karmaşık okuma ve analitik sorgularda ORM (Hibernate/JPA) katmanının yarattığı N+1 sorgu problemi ve çalışma zamanı (runtime) HQL/JPQL ayrıştırma maliyeti yerine SQL-öncelikli (SQL-first) derleme zamanı tip güvenliğinin kullanılmasıdır:

  • jOOQ MULTISET ve İç İçe Koleksiyonlar (Nested Collections): Geleneksel ORM'lerde bir ana kayıt ve ona bağlı birden fazla alt listeyi çekerken oluşan kartezyen çarpım (Cartesian product) patlaması veya çoklu sorgu yükü, jOOQ'un standart SQL MULTISET operatörüyle tek bir veritabanı sorgusunda çözülür.
  • Java record ile Doğrudan Eşleme (Ad-Hoc Type-Safe Mapping): Veritabanı şemasından üretilen jOOQ meta-verisi, Records.mapping(OrderSummaryDTO::new) aracılığıyla yansıma (reflection) kullanmadan doğrudan değişmez Java record nesnelerine dönüştürülür.
Mimari Katman / Özellik Eski / Geleneksel Java Yaklaşımı Modern JDK 27 & Spring Boot + jOOQ Yaklaşımı
Konteyner Varsayılan GC Küçük konteynerlerde Serial GC geri dönüşü JEP 523 ile her ortamda evrensel G1 GC
G1 Yığın Oranları (Min/MaxHeapFreeRatio) 40 / 70 (Full GC sonrası agresif boyut değişimi) 0 / 100 (CPU oranı tabanlı akıcı sezgisel boyutlandırma)
Kısa Ömürlü İş Parçacığı Belleği Sabit/büyük TLAB nedeniyle genç nesil bellek israfı JDK-8381834 ile dinamik ve tutumlu TLAB boyutlandırması
Çalışma Zamanı Güvenlik Modeli SecurityManager (Java 24'te tamamen kapatıldı) JPMS modülleri, konteyner izolasyonu, JEP 415 ObjectInputFilter
İlişkisel Alt Koleksiyon Sorgulama ORM N+1 sorguları veya Kartezyen çarpım tekrarı jOOQ MULTISET + Records.mapping() ile tek sorguda record projeksiyonu

Mühendislik Uygulaması: Güvenli Doğrulama (TOCTOU / Overflow) ve Spring Boot jOOQ MULTISET Deposu

Aşağıdaki Java referans uygulaması, güncellenen Java Secure Coding Guidelines ilkelerini (savunmacı List.copyOf() kopyalaması, Math.multiplyExact taşma koruması ve JEP 415 ObjectInputFilter) ve Spring Boot + jOOQ MULTISET ile tek sorguda değişmez record projeksiyonu yapan veri erişim katmanını bir arada göstermektedir:

java
package com.tastutanlabs.enterprise.order;

import org.jooq.DSLContext;
import org.jooq.Records;
import org.springframework.stereotype.Repository;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputFilter;
import java.io.ObjectInputStream;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static org.jooq.impl.DSL.*;
import static com.tastutanlabs.enterprise.jooq.Tables.ORDERS;
import static com.tastutanlabs.enterprise.jooq.Tables.ORDER_ITEMS;

// 1. Java Secure Coding Guidelines: Değişmez (Immutable) Record ve Savunmacı Kopyalama
public record OrderLineItemView(String sku, int quantity, BigDecimal unitPrice) {
    public OrderLineItemView {
        Objects.requireNonNull(sku, "SKU boş olamaz");
        Objects.requireNonNull(unitPrice, "Birim fiyat boş olamaz");
        if (quantity <= 0) {
            throw new IllegalArgumentException("Miktar pozitif olmalıdır");
        }
        // Tamsayı taşması (Integer Overflow) kontrolü
        Math.multiplyExact(quantity, 100);
    }
}

public record OrderSummaryView(
        UUID orderId,
        String customerEmail,
        Instant createdAt,
        List<OrderLineItemView> items
) {
    public OrderSummaryView {
        Objects.requireNonNull(orderId, "Sipariş kimliği zorunludur");
        Objects.requireNonNull(customerEmail, "Müşteri e-postası zorunludur");
        Objects.requireNonNull(createdAt, "Oluşturulma zamanı zorunludur");
        // TOCTOU zafiyetine karşı savunmacı değişmez kopya
        items = List.copyOf(items);
    }
}

@Repository
public class SecureOrderJooqRepository {

    private final DSLContext dsl;

    // JEP 415: Bağlama özgü katı beyaz liste serileştirme filtresi
    private static final ObjectInputFilter STRICT_AUDIT_FILTER = ObjectInputFilter.Config.createFilter(
            "maxdepth=3;maxarray=64;maxbytes=4096;java.base/*;!*");

    public SecureOrderJooqRepository(DSLContext dsl) {
        this.dsl = dsl;
    }

    // 2. jOOQ MULTISET: N+1 sorunu olmadan tek SQL sorgusunda iç içe koleksiyon projeksiyonu
    public List<OrderSummaryView> findRecentOrdersWithItems(String tenantId, int limitCount) {
        int safeLimit = Math.clamp(limitCount, 1, 100);

        return dsl.select(
                        ORDERS.ID,
                        ORDERS.CUSTOMER_EMAIL,
                        ORDERS.CREATED_AT,
                        multiset(
                                select(
                                        ORDER_ITEMS.SKU,
                                        ORDER_ITEMS.QUANTITY,
                                        ORDER_ITEMS.UNIT_PRICE
                                )
                                .from(ORDER_ITEMS)
                                .where(ORDER_ITEMS.ORDER_ID.eq(ORDERS.ID))
                        ).convertFrom(r -> r.map(Records.mapping(OrderLineItemView::new)))
                )
                .from(ORDERS)
                .where(ORDERS.TENANT_ID.eq(tenantId))
                .orderBy(ORDERS.CREATED_AT.desc())
                .limit(safeLimit)
                .fetch(Records.mapping(OrderSummaryView::new));
    }

    // 3. JEP 415 Filtreli Güvenli Okuma Yardımcı Metodu
    public Object deserializeTrustedAuditSnapshot(byte[] rawBytes) throws IOException, ClassNotFoundException {
        try (var bais = new ByteArrayInputStream(rawBytes);
             var ois = new ObjectInputStream(bais)) {
            ois.setObjectInputFilter(STRICT_AUDIT_FILTER);
            return ois.readObject();
        }
    }
}

[!TIP]
Üretim Performansı ve JVM Bayrak Önerisi: JDK 27'ye geçiş yapan mikroservislerde özel olarak tanımlanmış eski -XX:MinHeapFreeRatio ve -XX:MaxHeapFreeRatio parametreleri kaldırılarak JVM'in yeni 0 / 100 varsayılanlarıyla çalışmasına izin verilmelidir. Veri katmanında ise okuma ağırlıklı uç noktalarda JPA varlık grafikleri (@EntityGraph) yerine jOOQ MULTISET + Records.mapping() kullanılması hem GC üzerindeki geçici nesne (allocation rate) baskısını düşürür hem de derleme zamanı SQL güvenliği sağlar.

Konu Etiketleri
#Spring Boot#jOOQ#JDK 27#G1 GC#JEP 523#TLAB#Java Secure Coding#JEP 415
Emre Taştutan
Emre TaştutanGeliştirici & AI Meraklısı

Yazılım mimarisi, mikroservis ekosistemleri ve üretken yapay zeka uygulamaları üzerine çalışıyorum. TastutanLabs çatısı altında geliştirici araçları ve SaaS ürünleri inşa ediyorum.

@tastutanlabs • Instagram Mini-Blog

Bu analizin 6 kartlık görsel özetini Instagram'da inceleyin ve kaydedin

Her gün yazılım mimarisi, Java/JVM ve yapay zeka gelişmelerini kendi başına okunabilen 6 slaytlık Mini-Blog serileri halinde paylaşıyoruz.

Instagram'da Takip Et →
Bu Yazıyı Paylaş:

Yorumlar (0)

Düşüncelerinizi Paylaşın

Henüz yorum yapılmamış. İlk yorumu siz yapın!

Bu Kategorideki Diğer İncelemeler

Java & Kurumsal Mimari

OpenJDK ‘Project Detroit’ (FFM ile V8 ve CPython), Spring Boot Yerel ‘Cloud Foundry / kind’ Orkestrasyonu ve Quarkus 4.0 Mimarisi

OpenJDK'nın Foreign Function & Memory (FFM) API üzerinden Google V8 ve CPython çalışma zamanlarını doğrudan JVM sürecine gömen Project Detroit girişimi, Spring Boot uygulamalarında Docker/kind tabanlı yerel Cloud Foundry dağıtımı ve Quarkus 4.0 (Vert.x 5, HTTP/3, Hibernate 8) mimarisi inceleniyor.

Emre TaştutanEmre Taştutan
9 dk
Java & Kurumsal Mimari

JDK 28’de ‘JEP 401 Value Classes’ ve Değişmez Veri Mimarisi, Spring AI 2.1 ‘MessagePart’ Akıl Yürütme Korunumu ve Özel Vektör ‘Upsert’ API’si

OpenJDK 28 erken erişim sürümlerinde 30 çekirdek sınıfı kimliksiz değer nesnesine dönüştüren JEP 401 (Value Classes), çok turlu akıl yürütme imzalarını kayıpsız taşıyan Spring AI 2.1 MessagePart mimarisi ve önceden hesaplanmış float[] vektörleri destekleyen VectorStore.upsert() yetenekleri inceleniyor.

Emre TaştutanEmre Taştutan
10 dk