Statik alanlar çöp toplamaya açık mı?


96

Yalnızca program kurulumunda kullanılan varsayımsal bir fayda sınıfı verildiğinde:

class MyUtils {
   private static MyObject myObject = new MyObject();
   /*package*/static boolean doStuff(Params... params) {
       // do stuff with myObject and params...
   }
}

myObject artık kullanılmadığında çöp toplanacak mı yoksa programın ömrü boyunca ortalıkta mı kalacak?

Yanıtlar:


113

Statik değişkenler, sınıf yüklenirken çöp toplama için seçilemez. İlgili sınıf yükleyici (bu sınıfın yüklenmesinden sorumlu olan) kendisi çöp için toplandığında toplanabilirler.

Check out Sınıflar ve Arayüzler ve JLS Bölüm 12.7 Boşaltma

Bir sınıf veya arabirim, yalnızca ve ancak tanımlayıcı sınıf yükleyicisi çöp toplayıcı tarafından geri alınabilirse kaldırılabilir [...] Önyükleme yükleyicisi tarafından yüklenen sınıflar ve arabirimler kaldırılamaz.


@bruno, Bağlantınız başına, yüklenen sınıfın statik üyeleri olmasa bile, bir sınıf yükleyicinin yüklediği her sınıfa bir başvuru tuttuğu anlamına mı geliyor?
Pacerier

@brunoconde, bunun doğru olduğunu sanmıyorum. Tam olarak hangi paragraf bunu belirtir? (Lütfen stackoverflow.com/questions/405364/…
adresindeki

Sınıf yükleyicinin çöp toplama için uygun olduğu zaman. ?
Rohit Bandil

@RohitBandil - ulaşılamaz olduğunda.
Stephen C

55

Statik değişkenler, ClassLoaders tarafından referans verilen Class nesneleri tarafından referans alınır - bu nedenle ya ClassLoader Sınıfı bir şekilde düşürmedikçe (bu mümkünse) ya da ClassLoader'ın kendisi toplama için uygun hale gelmedikçe (daha olasılıkla - web uygulamalarını kaldırmayı düşünün) statik değişkenler (veya bunun yerine referans verdikleri nesneler) toplanmaz.


1
Do Classhiçbir statik değişken içermeleri nesnelerin kendi sınıf yükleyicisi tarafından başvurulan olsun?
Pacerier

14

Statik başlatma için geçici bir nesnenin kullanılmasını ve ardından atılmasını istiyorsanız, bir statik başlatıcı bloğu kullanabilirsiniz, örn.

class MyUtils {
   static
   {
      MyObject myObject = new MyObject();
      doStuff(myObject, params);
   }

   static boolean doStuff(MyObject myObject, Params... params) {
       // do stuff with myObject and params...
   }
}

Statik başlatıcı bloğu özel bir statik yöntem türü olduğundan, myObject yerel bir değişkendir ve bloğun yürütülmesi bittikten sonra çöp toplanabilir.


13

myObject bir nesnedir , bir referanstır . Bir nesne, erişilemez olduğu için kendisine hiçbir referans göstermediğinde otomatik olarak çöp toplanır.

Dolayısıyla, statik bir referans olan "myObject" arkasındaki nesne de, referansını kaldırırsanız çöp toplanabilir.

myObject = null;

ve bu nesneye başka referans yok.

Bununla birlikte, statik başvurular ve değişkenler programınızın ömrü boyunca kalır.


StackOverflow'a hoş geldiniz! nullSonunda nesneyi ayarlamak static blockuygun bir seçenektir. Benim durumumda, nesnenin yaşam süresinin statik bloktan daha uzun olması gerekiyordu. Nesnenin yararlılığı çok somut değildi; bu yüzden çöp toplayıcının kullanımıyla ilgili sorum.
Michael Deardeuff

7

Sanırım bu , sorunuzu yanıtlıyor - temelde sınıf özel bir sınıf yükleyiciden gelmedikçe ve bu sınıfın yükünü kaldırmazsa.


0

Buradaki anahtar, Sınıf örneklerinin, yani Nesnelerin Çöp Toplamasıdır. ClassLoader örneği özünde bir Nesnedir. Dolayısıyla, Classloader nesnesi çöp olarak toplanmadıysa, bunların yığın içinde depolanan referansları (yani statik şeyler) neredeyse hiçbir zaman çöp olarak toplanmayacaktır. İstisna, String havuzudur.

Yani aniden yapmaya karar vermeden önce private static MyGiantClass myGiantObject = new MyGiantClass() , benim zor yoldan öğrendiğim gibi iki kez düşünün.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.