2012-10-15 11 views
9

Çok sayıda yinelenen Dizeye sahip bir uygulama üzerinde çalışıyorum ve görevim bunları bellek kullanımını azaltmak için ortadan kaldırmaktır. İlk düşüncem, bir String'in sadece bir referansının mevcut olacağını garanti etmek için String.intern'u kullanmaktı. Yığın belleğini azaltmak için çalıştı, ancak PermGen yolunu çok artırdı; Aslında, yalnızca bir kez bildirilen birçok dizeler olduğu için, uygulamanın kullandığı toplam bellek miktarı artmıştır.Bellek kullanımını artırmadan her zaman bir String'e aynı referansı kullanmak için kodu nasıl optimize edebilirim?

Başka bir fikir ararken, şu yaklaşımı buldum: https://stackoverflow.com/a/725822/1384913.

String.intern ile aynı şey oldu: Dize kullanımı azaldı, ancak kaydettiğim bellek WeakHashMap ve WeakHashMap$Entry sınıflarında kullanılıyor.

Yapmakta olduğum miktarda bellek harcayan her bir String için yalnızca bir referansı korumanın etkili bir yolu var mı?

+2

Bir 'WeakHashMap' kokan Yeterince hafıza kurtaracak, muhtemelen bunu yapmanın bir yolu yoktur. Bir 'WeakHashMap', gerçekçi bir şekilde, 'String'i belirli bir değer için aramak için çok fazla çalışma zamanına mal olmayacak tek çözüm olacak. –

+3

Benzer bir soruya verdiğim yanıta da bakabilirsiniz http://stackoverflow.com/a/12793823/57695 –

+0

Açık bir nokta, ancak farklı Strings kaynaklarını sınıflandırabiliyorsanız (örneğin, çok fazla yinelenenler arasında ayrım yapabilirsiniz) Bir keresinde kullanılanlara karşı) daha sonra bunu daha verimli yapabilirsiniz. Bu sizin uygulama için mümkün olmayabilir ... – DNA

cevap

1

WeakHashMap'a bir alternatif buldum: Eclipse JDT kitaplığı tarafından sağlanan WeakHashSet. Aynı davranış WeakHashMap, ancak daha az bellek kullanır. Ayrıca, yalnızca add yöntemini çağırmanız yeterlidir ve henüz mevcut değilse veya mevcut olanı döndürdüğünde dizgiyi kümeye ekler.

Beğenmediğim tek şey, jeneriği kullanmamaları ve geliştiricilerin nesneleri kullanmaları için zorlamalarıdır. WeakHashSet ait

Bildirgesi:

private static WeakHashSet stringPool = new WeakHashSet(30000); //30 thousand is the average number of Strings that the application keeps. 

ve stajyer yöntemi: Eğer feryat gördüğünüz gibi benim intern yöntemi oldukça basit olduğu ortaya çıktı

public static String intern(String value) { 
    if(value == null) { 
     return null; 
    } 
    return (String) stringPool.add(value); 
} 
0

Neden String yerine StringBuilder/StringBuffer sınıfını kullanmıyorsunuz? Bu sınıfın örneğini kullanarak, her zaman aynı örneği farklı değerler ile kullanabilirsiniz. - Ankur

0

Benzer bir durumda, mümkün olan her durumda, dize sabitlerini enums'e geri yükledim. Bu şekilde, iki faydası olsun:

  • enum örnekleri singletons, bu yüzden Dizeleri kullanırken bellek sorunları
  • hiçbir yazım hatası olmaz.

Eksileri: Eğer

  • yeterli test durumları yoksa

    • bir çok eserin, sonsuz olanaklar ile bazen bu zaman sizi örneğin önemsiz değildir, hata yapma Sadece düzenleme yapamayacağınız üçüncü parti kütüphanelerle etkileşime girmelisiniz ...
    • Bunlar çalışma zamanı belirlendiyse basitçe bir no-go ve zaman derleme ...
  • İlgili konular