ऑब्जेक्ट पूलिंग एक पदावनत तकनीक है?


62

मैं ऑब्जेक्ट पूलिंग की अवधारणा से बहुत परिचित हूं और मैं हमेशा इसका यथासंभव उपयोग करने की कोशिश करता हूं।

इसके अतिरिक्त मुझे हमेशा लगता था कि ऑब्जेक्ट पूलिंग मानक मानदंड है जैसा कि मैंने देखा है कि जावा स्वयं के साथ-साथ अन्य चौखटे जितना संभव हो उतना पूलिंग का उपयोग करता है।

हाल ही में हालांकि मैंने कुछ पढ़ा जो मेरे लिए बिल्कुल नया था (और जवाबी सहज?)।

वह पूलिंग वास्तव में कार्यक्रम के प्रदर्शन को विशेष रूप से समवर्ती अनुप्रयोगों में बदतर बना देता है, और इसके newबजाय वस्तुओं को तत्काल करने की सलाह दी जाती है , क्योंकि नए जेवीएम में, किसी वस्तु का तात्कालिकता वास्तव में तेज है।

मैंने इसे पुस्तक में पढ़ा: Java Concurrency in Practice

अब मैं सोचना शुरू कर रहा हूं कि क्या मैं कुछ गलतफहमी कर रहा हूं क्योंकि किताब के पहले भाग ने नए उदाहरण बनाने के बजाय Executorsउस पुन: उपयोग का उपयोग करने की सलाह दी है Thread

तो क्या ऑब्जेक्ट पूलिंग आजकल पदावनत हो गया है?

जवाबों:


72

इसे एक सामान्य तकनीक के रूप में चित्रित किया गया है, क्योंकि - जैसा कि आपने देखा - प्रति सेकंड (यानी मेमोरी आवंटन और जीसी) की कम जीवित वस्तुओं का निर्माण और विनाश आधुनिक जेवीएम में बेहद सस्ता है। इसलिए अपने रन-ऑफ-द-मिल ऑब्जेक्ट्स के लिए हाथ से लिखे ऑब्जेक्ट पूल का उपयोग करना सबसे अधिक संभावना है, सादे से अधिक जटिल और अधिक त्रुटि-प्रवण new। *

यह अभी भी इसके उपयोग करता है, हालांकि, विशेष वस्तुओं के लिए जिनकी रचना अपेक्षाकृत महंगी है, जैसे डीबी / नेटवर्क कनेक्शन, थ्रेड्स आदि।

* एक बार मुझे क्रॉलिंग जावा ऐप के प्रदर्शन में सुधार करना था। जांच ने लाखों ऑब्जेक्टों को आवंटित करने के लिए एक ऑब्जेक्ट पूल का उपयोग करने का प्रयास किया ... और चतुर व्यक्ति जिसने इसे लिखा था, इसे थ्रेड को सुरक्षित बनाने के लिए एक एकल वैश्विक लॉक का उपयोग किया। सादा के साथ पूल को बदलने से newऐप 30 गुना तेज हो गया।


1
तो कोई कैसे तय कर सकता है कि किसी वस्तु की तात्कालिकता बहुत महंगी है?
user10326

3
यदि ऑब्जेक्ट ऑपरेटिंग सिस्टम रिसोर्सेस (थ्रेड्स, I / O, शेयर्ड मेमोरी, आदि) का
उपभोग करता है

13
@ user10326, माप से :-) यदि आपकी वस्तुओं को बनाने में एक लू लगने का समय लगता है, और / या वे कुछ विशेष, संभावित सीमित, गैर-मेमोरी संसाधन से जुड़े हैं, तो आप पूलिंग पर विचार कर सकते हैं।
पेर्ट टॉर्क

8
@ user10326, 95% से अधिक मामलों में IMO, उपरोक्त मानदंड अग्रिम में यह तय करना आसान बनाता है कि आपको ऑब्जेक्ट पूल की आवश्यकता है या नहीं। (इसके अलावा, लगभग सभी मामलों में एक पूल की आवश्यकता होती है, आप संभवतः एक मौजूदा लाइब्रेरी / फ्रेमवर्क का उपयोग करेंगे, जो संभवतः आपके लिए पहले से लागू किया गया ऑब्जेक्ट पूल है।) बाकी के लिए, जैसे अभी भी ऑब्जेक्ट निर्माण को छिपाना आसान है। एक कारखाना, जिसे बाद में जिस भी तरीके से आप फिट देखते हैं, उसे फिर से लागू किया जा सकता है।
पेर्ट टॉर्क

2
@Peter Torok द्वारा बनाया गया बहुत महत्वपूर्ण बिंदु: कई चौखटे और पुस्तकालय आपके लिए पूलिंग को लागू करते हैं, हमेशा सुनिश्चित करें कि आप अपने स्वयं के कार्यान्वयन से पहले पूलित पुस्तकालय का उपयोग नहीं कर रहे हैं।
hromanko

36

ठोस सवाल का जवाब: 'क्या ऑब्जेक्ट एक अपग्रेड की गई तकनीक है?' है:

नंबर ऑब्जेक्ट पूलिंग का व्यापक रूप से विशिष्ट स्थानों पर उपयोग किया जाता है - थ्रेड पूलिंग, डेटाबेस कनेक्शन पूलिंग आदि।

सामान्य वस्तु निर्माण कभी भी एक धीमी प्रक्रिया नहीं रही है। अपने आप में पूलिंग करने से संसाधनों की खपत होती है - मेमोरी और प्रोसेसिंग पावर। कोई भी अनुकूलन एक व्यापार बंद है।

नियम है:

शीघ्र अनुकूलन बुराई है !!!

लेकिन किसी दिए गए अनुकूलन को समय से पहले कब लिया जाता है?

समय से पहले अनुकूलन किसी भी अनुकूलन किया जाता है, इससे पहले कि आप पूरी तरह से रूपरेखा के माध्यम से एक अड़चन को उजागर किया है


2
वास्तव में। ओपी ने कहा "मैं हमेशा इसका यथासंभव उपयोग करने की कोशिश करता हूं" - यह समस्या है, आईएमओ।
nerdytenor

@ बोरिस, तो आपके दूसरे वाक्य के अनुसार, हमें पूल डीबी कनेक्शन और थ्रेड्स पर आपत्ति नहीं करनी चाहिए जब तक कि हम उन्हें प्रोफाइलिंग के माध्यम से एक अड़चन के रूप में उजागर न करें?
पेसियर

1
@Pac कुछ प्रोफाइलिंग परिणामों को निरंतर पुन: मापने की आवश्यकता नहीं होती है :-)
डेविड बुलॉक

9

उन स्थितियों में जहां आप पूरी तरह से कचरा संग्रह से बचना चाहते हैं, मुझे लगता है कि ऑब्जेक्ट पूलिंग एकमात्र व्यवहार्य विकल्प है। तो नहीं, यह पूरी तरह से एक पदावनत तकनीक नहीं है।


1
और मैं यह जोड़ूंगा कि जब भी ऑब्जेक्ट लंबे समय तक जीवित रहते हैं, तो जीसी से बचने के लिए यह एक अच्छा विचार है कि वे पुरानी पीढ़ी में चले गए हैं।
ज़ैन लिंक्स

8

उपाय

यह पूरी तरह से आपके उपयोग के मामले, आपकी वस्तुओं के आकार, आपके जेवीएम, आपके जेवीएम विकल्प, जीसी आपके द्वारा सक्षम और अन्य कारकों की एक पूरी मेजबानी पर निर्भर करता है।

संक्षेप में: इसे पहले मापें और बाद में मापें। मान लें कि आप ऑब्जेक्ट पूलिंग फ्रेमवर्क का उपयोग कर रहे हैं (जैसे अपाचे से) तो इसे क्रियान्वयन के बीच स्वैप करने के लिए बहुत दर्दनाक नहीं होना चाहिए।

अतिरिक्त प्रदर्शन परीक्षण टिप - पहले जेवीएम को थोड़ा गर्म होने दें, कई बार चल रहे जेवीएम पर परीक्षण चलाएं, यह अलग-अलग व्यवहार कर सकता है।


3
"पहले जेवीएम को थोड़ा गर्म होने दें," - मुझे याद है जब केवल एक चीज जिसे "वार्म अप" किया जाना था, वह थी मॉनिटर। ओए, सब कुछ फिर से पुराना है।
काइलबेन

केवल एक चीज जिसे मुझे गर्म करने की ज़रूरत है वह है कॉफी!
मोहभंग हुआ

@ मारिजान, आप इसे "वार्म अप" कैसे करते हैं?
पेसियर

पूर्ण विवरण के लिए JMH फ्रेमवर्क देखें ( Openjdk.java.net/projects/code-tools/jmh ) लेकिन मूल रूप से आपको JVM को अपना कोड JIT करने का मौका देने के लिए मिला है, GC के बेंचमार्क से पहले दौड़ें आदि।
मार्टिज़न वर्बर्ग

8

वह पूलिंग वास्तव में कार्यक्रम के प्रदर्शन को विशेष रूप से समवर्ती अनुप्रयोगों में बदतर बना देता है, और इसके बजाय नई वस्तुओं को त्वरित करने की सलाह दी जाती है, क्योंकि नए जेवीएम में, किसी वस्तु की तात्कालिकता वास्तव में तेज होती है।

संदर्भ पर निर्भर करता है।


1
उत्कृष्ट उत्तर, और दलदली। मैं जोड़ सकता हूं (शायद, एक तारांकन के रूप में?) कि "24 बाइट्स" का दावा 4-बाइट फ़्लोट्स (16 बाइट्स) के 4 उदाहरणों को संदर्भित करता है, प्लस 4 संदर्भ के लिए बाइट्स, प्लस एक लॉक संदर्भ के लिए 4 बाइट्स। यह सटीक ओवरहेड है जिससे आपका डिज़ाइन समाप्त हो जाता है।
स्ट्रिकली

5

मुझे नहीं पता कि यहां कोई परिवर्तन हुआ है या नहीं, लेकिन निश्चित रूप से ऐसा होने जा रहा है जो कि निर्भर करता है । यदि आपका जावा वर्ग एक बाहरी संसाधन का प्रबंधन कर रहा है, जैसे कि एक आरएमआई कनेक्शन या संसाधन फ़ाइल लोड करना आदि - तो निश्चित रूप से वस्तु तात्कालिकता के लिए लागत अभी भी अधिक हो सकती है (हालांकि उन संसाधनों को आपके लिए पहले से ही जमा किया जा सकता है!)। एक सामान्य अभ्यास के रूप में मैं पुस्तक से सहमत हूँ।


खैर अब मुझे पता नहीं है। हालांकि इस मामले में भी आप इसका वर्णन करें (जो इसे पढ़ने से पहले) मैं निश्चित रूप से पूलिंग का उपयोग करूंगा, मेरे पास ओवरहेड 1 भी होगा। पूलिंग को संभालने के लिए नए निर्माण 2) ऑब्जेक्ट प्राप्त करने / रिले करने के लिए सिंक्रनाइज़ेशन पूल 3 से) पूल बनाए रखना आदि। इसलिए मैं अब सोच रहा हूं कि शायद कोई उपयोग मामला नहीं है कि यह उपयोगी है जैसे कि सर्वर से कनेक्ट करने के लिए हर बार एक नया खोलने के बजाय एक सॉकेट को कैशिंग करना। और यह मामला नेटवर्क के कारण है विलंबता और
इंस्टेंटेशन

@ user10326 हां बिल्कुल। मैं तात्कालिक ओवरहेड के हिस्से के रूप में एक सॉकेट खोलते हुए देखता हूं, अगर इसकी कक्षा का काम यह करना है और इसे कंस्ट्रक्टर में आरंभीकृत किया जाना चाहिए तो विलंबता और IO प्रभाव आप के साथ संबंधित हैं।
जेरेमी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.