ProgramlamaKıdemli Java Backend Geliştirici

Java'da sınıf yükleme mekanizması (class loading) nasıl çalışır, hangi sınıf yükleyici türleri vardır ve bunların yanlış kullanımında ortaya çıkabilecek sorunlar nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Java'da sınıflar, özel nesneler olan sınıf yükleyicileri (class loaders) tarafından belleğe yüklenir. Her sınıf yükleyici, kendi sınıf görünürlük alanını oluşturur.

Sınıf yükleyici türleri:

  1. Bootstrap ClassLoader — JDK'nin temel sınıflarını (rt.jar vb.) yükler.
  2. Extension ClassLoader$JAVA_HOME/lib/ext içindeki uzantıları yükler.
  3. System (Application) ClassLoader — uygulamanın classpath'indeki sınıfları yükler.
  4. Custom ClassLoader — dinamik yükleme için kullanıcı tanımlı yükleyicilerdir.

Özellikler:

  • Sınıf, (class loader, sınıf adı) kombinasyonu kapsamında benzersiz kabul edilir.
  • Farklı yükleyiciler tarafından yüklenen aynı sınıflar, farklı kabul edilir.
  • Sınıf yükleyicileri bir hiyerarşi oluşturur (ebeveyn-çocuk).
  • Sınıflar byte'lar üzerinden yüklenebilir (defineClass) — bu, eklentiler/JSP vb. için geçerlidir.

Soruya dikkat.

JVM sürecine aynı sınıfın birden fazla versiyonunu yüklemek mümkün mü ve nasıl yapılır?

Cevap: Evet, mümkündür; eğer farklı sınıf yükleyicileri kullanılırsa. Aynı FQDN'ye sahip sınıflar, farklı yükleyiciler tarafından yüklendiğinde JVM için farklı türler olarak kabul edilir.

Örnek:

ClassLoader loader1 = new URLClassLoader(new URL[]{...}); ClassLoader loader2 = new URLClassLoader(new URL[]{...}); Class clazz1 = loader1.loadClass("com.example.MyClass"); Class clazz2 = loader2.loadClass("com.example.MyClass"); System.out.println(clazz1 == clazz2); // false

Konunun inceliklerinden dolayı ortaya çıkan gerçek hata örnekleri.


Hikaye

Büyük bir sunucu sisteminde, her biri ayrı bir custom classloader ile bağlanan eklentiler kullanılıyordu. Eklentiler, kendi sınıf yükleyicileri tarafından yüklenen ortak bir arayüz üzerinden nesneleri değiş tokuş ediyordu. 'PluginApi' arayüzü, eklenti sınıf yükleyicisinden ve ana sistemden farklı türler olarak kabul edildiği için ClassCastException hatası meydana geldi.


Hikaye

Bir custom classloader aracılığıyla " sıcak" servlet yeniden yükleme girişimi, bellek sızıntılarına yol açtı — eski sınıf bellekten atılmadı, çünkü statik değişkenlerin bir yerinde hala bir referans vardı. Sonuç olarak PermGen hızlı bir şekilde doldu.


Hikaye

Dinamik modül yükleme desteğine sahip bir ürün, sistem sınıf yükleyicisini dolaylı olarak kullanıyordu ve geliştiriciler yanlışlıkla ebeveynini değiştirdi, bu da temel sınıflara (örneğin, JDK'den) erişimi kaybetmelerine yol açtı. Bu, yeni modülün standart Java sınıflarını, örneğin, java.sql.Driver yükleyememesi durumunda çökmelere yol açtı.