Nesne havuzu kullanımdan kaldırılmış bir teknik midir?


62

Nesne havuzu kavramına çok aşinayım ve her zaman mümkün olduğunca kullanmaya çalışıyorum.

Ek olarak, her zaman nesne havuzlamanın standart Java olduğunu düşündüm, Java'nın ve diğer çerçevelerin kendisinin mümkün olduğunca havuz kullandığını gözlemledim.

Son zamanlarda benim için tamamen yeni (ve karşı sezgisel?) Bir şey okudum.

Bu havuzlama, özellikle eşzamanlı uygulamalarda program performansını daha da kötüleştirir ve bunun newyerine nesnelerin başlatılması önerilir çünkü yeni JVM'lerde nesnenin başlatılması gerçekten hızlıdır.

Bunu kitapta okudum: Java Concurrency in Practice

Şimdi, burada bir şeyi yanlış anlıyorsam, kitabın ilk örneklerinden yeni örnekleri Executorskullanmak Threadyerine bu yeniden kullanımları önerdiği için düşünmeye başlıyorum .

Öyleyse, nesne havuzu günümüzde kullanımdan kaldırıldı mı?

Yanıtlar:


72

Genel bir teknik olarak kullanımdan kaldırılmıştır, çünkü - fark ettiğiniz gibi - kısa ömürlü nesnelerin yaratılması ve yok edilmesi modern JVM'lerde oldukça ucuzdur. Bu nedenle, değirmen bitmiş nesneleriniz için elle yazılmış bir nesne havuzu kullanmak, büyük olasılıkla daha yavaş, daha karmaşık ve düz olmaktan daha fazla hataya meyillidir new. *

Yine de kullanımları vardır; DB / ağ bağlantıları, iplikler vb.

* Bir zamanlar sürünen bir Java uygulamasının performansını artırmak zorunda kaldım. Soruşturma, milyonlarca nesneyi tahsis etmek için bir nesne havuzu kullanma girişimini ortaya çıkardı ... ve onu yazan zeki adam, iş parçacığını güvenli hale getirmek için tek bir küresel kilit kullandı. Havuzun düz ile değiştirilmesi, newuygulamayı 30 kat daha hızlı hale getirdi.


1
Öyleyse, bir nesnenin somutlaştırılmasının çok pahalı olup olmadığına nasıl karar verilebilir?
user10326,

3
Nesne işletim sistemi kaynaklarını kullanıyorsa (iş parçacığı, G / Ç, paylaşılan bellek vb.)
kevin cline

13
@ user10326, ölçüme göre :-) Nesnelerinizi oluşturmak çok uzun zaman alıyorsa ve / veya bazı özel, potansiyel olarak sınırlı, bellek dışı kaynaklarla ilişkiliyse, havuzlamayı düşünebilirsiniz.
Péter Török,

8
@ user10326, IMO vakaların% 95'inde, yukarıdaki kriterler bir nesne havuzuna ihtiyacınız olup olmadığına önceden karar vermenizi kolaylaştırır. (Ayrıca, bir havuza ihtiyaç duyan hemen hemen tüm durumlarda, muhtemelen sizin için zaten oluşturulmuş nesne havuzunu içeren mevcut bir kütüphane / çerçeveyi kullanacaksınız.) Geri kalanı için, örneğin nesne oluşturmayı gizlemek kolaydır. daha sonra hangi şekilde uygun gördüğünüzü tekrar uygulayabileceğiniz bir fabrika.
Péter Török,

2
@Peter Torok tarafından çok önemli bir nokta: birçok çerçeve ve kütüphane sizin için havuz oluşturuyor, HER ZAMAN kendi havuzunuzu uygulamadan önce bir havuzlu kütüphane kullanmadığınızdan emin olun.
hromanko 19:11

36

Somut sorunun cevabı: 'Nesne, kullanımdan kaldırılmış bir tekniği bir araya getiriyor mu?' dır-dir:

Hayır. Nesne havuzu, belirli yerlerde yaygın olarak kullanılır - iş parçacığı havuzu, veritabanı bağlantı havuzu vb.

Genel nesne oluşturma hiç yavaş bir işlem olmamıştır. Kendi içinde havuzlamak, kaynakları tüketir - bellek ve işlem gücü. Herhangi bir optimizasyon bir takas.

Kural:

Erken Optimizasyon Kötü!

Fakat verilen bir optimizasyon ne zaman erken olur?

Erken optimizasyon, ayrıntılı bir profilleme yoluyla bir darboğazı çözmeden önce yapılan herhangi bir optimizasyondur .


2
Aslında. OP “Her zaman mümkün olduğunca kullanmaya çalışıyorum” dedi - sorun bu, IMO.
nerdytenor

@ Boris, Öyleyse ikinci cümlesine göre, havuz db bağlantılarını ve ipuçlarını profilleme yoluyla bir darboğaz olarak ortaya çıkartana kadar itiraz etmemeliyiz?
Pacerier

1
@Pac Bazı profil oluşturma sonuçlarının sürekli olarak yeniden ölçülmesine gerek yoktur :-)
David Bullock

9

Tamamen çöp toplanmasından kaçınmak istediğiniz durumlarda, nesne toplamanın tek geçerli alternatif olduğunu düşünüyorum. Yani hayır, kesinlikle kullanımdan kaldırılmış bir teknik değildir.


1
Ayrıca, nesnelerin eski nesle taşınacak kadar uzun ömürlü olmaları durumunda GC'den kaçınmanın iyi bir fikir olduğunu da ekleyeceğim.
Zan Lynx

8

Ölçmek, ölçü,,, tedbir, önlem

Tamamen kullanım durumunuza, nesnelerinizin boyutuna, JVM'nize, JVM seçeneklerine, hangi GC'yi etkinleştirdiğinize ve bir dizi başka faktöre bağlıdır.

Kısacası: önce ölçün ve sonra ölçün. Bir nesne havuzlama çerçevesi kullandığınızı varsayarsak (Apache'den olduğu gibi), uygulamalar arasında değiş tokuş yapmak çok acı verici olmamalıdır.

Ekstra performans testi ipucu - önce JVM'nin biraz ısınmasına izin verin, çalışan bir JVM'de testleri birkaç kez çalıştırın, farklı şekilde davranabilir.


3
“önce JVM'nin biraz ısınmasına izin verin”, - “ısınması gereken” tek şeyin ne zaman monitör olduğunu hatırlıyorum. Oy, yeni olan her şey yine eski.
kylben

Isınmam gereken tek şey kahve!
Hayal kırıklığına uğradı

@ Marijn, Nasıl ısınmasına izin veriyorsun?
Pacerier

Tam bir açıklama için JMH Çerçevesine bakın ( openjdk.java.net/projects/code-tools/jmh ) ancak temel olarak JVM'ye kodunuzu JIT'e koyma şansı vermeniz gerekir.
Martijn Verburg

8

Bu havuzlama, özellikle eşzamanlı uygulamalarda program performansını daha da kötüleştirir ve bunun yerine yeni nesnelerin başlatılması önerilir çünkü yeni JVM'lerde nesnenin başlatılması gerçekten hızlıdır.

Bağlama göre değişir.


1
Mükemmel cevap ve cogent. "24 bayt" iddiasının 4 baytlık float (16 bayt), artı nesne başvurusu için 4 bayt, artı bir kilit başvurusu için 4 bayt anlamına geldiğini ekleyebilirim (belki de bir yıldız işareti?). Bu, tasarımınızın ortadan kaldırdığı yüküdür.
strickli

5

Değişen bir eğilim olup olmadığını bilmiyorum ama kesinlikle buna bağlı olacağı kesin . Java sınıfınız RMI bağlantısı veya kaynak dosyası yükleme gibi harici bir kaynağı yönetiyorsa - kesinlikle nesne başlatmanın maliyeti hala yüksek olabilir (bu kaynaklar sizin için zaten havuzlanmış olsa bile!). Genel bir uygulama olarak kitapla aynı fikirdeyim.


Peki şimdi bilmiyorum. Çünkü bu durumda bile (bunu okumadan önce) kesinlikle havuz kullanacağımı, ek yükü de kullanabileceğimi açıklarsınız. 1) Havuzlamayı ele almak için yeni yapılar 2) Alma / bırakma nesnesi için senkronizasyon havuzdan 3) havuzun bakımını yapmak vs. Bu yüzden şimdi, sunucuya bağlanmak için her seferinde yeni bir tane açmak yerine bir soketi önbelleğe almak dışında yararlı bir durum olmadığını düşünüyorum. Ve bu durum ağ nedeniyle gecikme süresi değil, örnekleme oluşturma ek yükü
user10326

@ user10326 Evet tam olarak. Sınıfın bunu yapması için yapıcıda başlatılması gerekiyorsa, gecikmeyi ve G / Ç etkilerini ilgilendirmeniz durumunda, bir prizi açılış başlığının bir parçası olarak görüyorum.
Jeremy
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.