post-images/dont-use-finalize-and-cleaner/cover.jpg

finalize() ve Cleaner Kullanmayın!

Bugün biraz daha derine dalıp Effective Java kitabının ilk ünitesi olan Creating and Destroying Objects'in 8. maddesini ele alacağız.

Konumuzun detayına gelirsek Object sınıfımızın finalize() metodu ve Cleaner sınıfını inceleyeceğiz. Java 9 ile beraber finalize() metodu deprecate olup kendi işini Cleaner sınıfına devretmiştir. Detaylı bilgi için incelemek isteyenlere; OpenJDK Doc.

finalize() metodu, obje uzun zaman kullanılmadığı durumda ve garbage collector temizlemeye gelmeden önce çalışmak üzere kullanılan bir metoddur. Geliştirici kullandığı objenin bellekten silinmeden önce yaptırmak istediği bir işlem varsa bu metodu override ederek kullansın mottosuyla yaratılmıştır. finalize() metodunun neden kullanılmaması gerektiğinin temel nedeni kullanıcı kendi implementasyonunu yaptığı durum için objesi boşa çıktığı durumda garbage collector'un ne zaman gelip temizleyeceği hatta temizleyip temizlemeyeceği bilgisi belli değildir. Nesne boşa çıktığı durumda hemen çalıştırılmasını istediğiniz bir metod için asla kullanılmamalıdır. Belli bir süre sonrasında projenin OutOfMemoryError hatası vermesine neden olabilir.

Cleaner sınıfı finalize() metoduna karşın daha avantajlıdır. Bu avantaj thread'ların sınıfı yazan kişinin kontrolünde olmasıdır. Fakat Cleaner sınıfıda garbage collector kontrolü altında olduğundan ne zaman temizleneceğinin garantisi yoktur.

finalize() metodu diğer bir dezavantajı da exception'ların yakalanmıyor olmasıdır. Bu yapı içerisinde herhangi bir hata olduğunda hatayı yakalayamazsınız, program durmaz ve stack trace basılmaz. Cleaner için bu problem söz konusu değildir çünkü yazan kişi bunu kontrol edebilir durumdadır.

Diğer bir sorun ise güvenlik açığıdır. Finalizer atack olarak geçen bu yöntem eğer bir constractor içerisinde exception atılıyorsa bu sınıf kalıtılıp, kalıtıldığı metod içerisinde finalize metodu yazılabilir. Bu yazilan finalize() metodu obje içerisinde statik bir değer tanımlarsa objenin referansı bellekte kalacağından garbage collector tarafından yakalanamaz. Bu durumu çözmek için boş bir final finalize() yazılabilir bu sayede değiştirilemeyeceği garanti altına alınmış olur.

Peki mesela bellekten silmeden hemen önce yaptırmayı düşündüğümüz bir olay için ne yapmamız gerekiyor? Bu işlem dosya kapama veya herhangi bir connection sonlandırma olabilir. Sınıfınıza AutoCloseable imlement edebilirsiniz. Her oluşan instance uzun zaman kullanılmadığında close() metodunun çağrılması gerekir. Herhangi bir exception'ın alınabileceği durumda try-with-resources kullanın. Bu konu hakkında daha detaylı bilgi için seni 9.maddeyi okumaya davet ediyorum.

JavaEffective JavaCreating and Destroying Objectsfinalize()Cleaner ClassAutoCloseabletry-finallly