2012-11-13 13 views
5

मैं विस्फोटों में लॉग इन करने और डेटा पथ को अनुकूलित करने के लिए बहुत सी चीजें लिख रहा हूं। मैं StringBuilder के साथ लॉग टेक्स्ट का निर्माण करता हूं। सबसे कुशल प्रारंभिक क्षमता, स्मृति प्रबंधन के अनुसार क्या होगा, तो यह JVM के बावजूद अच्छी तरह से काम करेगा? लक्ष्य लगभग हमेशा पुनर्वितरण से बचने के लिए है, जिसे लगभग 80-100 की प्रारंभिक क्षमता से ढंकना चाहिए। लेकिन मैं जितना संभव हो उतना बाइट बर्बाद करना चाहता हूं, क्योंकि स्ट्रिंगबिल्डर उदाहरण बफर में चारों ओर लटका सकता है और बर्बाद बाइट फसल हो सकता है।स्ट्रिंगबिल्डर के लिए सबसे कुशल प्रारंभिक क्षमता आकार?

मुझे एहसास है कि यह जेवीएम पर निर्भर करता है, लेकिन कुछ मूल्य होना चाहिए, जो कम से कम बाइट्स को बर्बाद कर देगा, इससे कोई फर्क नहीं पड़ता कि जेवीएम, "कम से कम आम संप्रदाय" का प्रकार है। मैं वर्तमान में 128-16 का उपयोग कर रहा हूं, जहां 128 एक अच्छा दौर संख्या है, और घटाव आवंटन ओवरहेड के लिए है। इसके अलावा, इसे "समयपूर्व अनुकूलन" का मामला माना जा सकता है, लेकिन चूंकि मैं बाद में उत्तर "नियम-का-अंगूठे" नंबर हूं, यह जानकर कि यह भविष्य में भी उपयोगी होगा।

मुझे "मेरे सबसे अच्छे अनुमान" उत्तरों की उम्मीद नहीं है (मेरा स्वयं का उत्तर पहले से ही है), मुझे उम्मीद है कि किसी ने पहले से ही इसका शोध किया है और ज्ञान आधारित उत्तर साझा कर सकता है।

+0

इस प्रश्न का उत्तर बहुत सारी चीजों पर निर्भर करता है, उदाहरण के लिए पाठ को 'स्ट्रिंगबिल्डर' में संग्रहीत करना कितना समय है। पता लगाने का एकमात्र तरीका स्मृति और/या CPU प्रोफाइलर का उपयोग करके मापना है। कुछ बाइट्स के बारे में चिंता करने का कोई कारण नहीं है जब तक कि आप सैकड़ों हजारों 'स्ट्रिंगबिल्डर' ऑब्जेक्ट्स बना रहे हों। – Jesper

+1

अब तक का सबसे बड़ा ओवरहेड आईओ की लागत है। जब तक आप इस डेटा को आईओ को लिखना नहीं चाहते हैं, तो मैं इसके बारे में चिंता नहीं करता। –

उत्तर

3

ठीक है, मैंने इसे संक्षिप्त रूप से परीक्षण करने का अंत किया, और फिर इस संपादित उत्तर प्राप्त करने के लिए टिप्पणियों के बाद कुछ और परीक्षण किया।

JDK 1.7.0_07 का प्रयोग और परीक्षण ऐप्लिकेशन रिपोर्टिंग वीएम नाम "जावा हॉटस्पॉट (टीएम) 64-बिट सर्वर वी एम", StringBuilder स्मृति के उपयोग के विवरण के स्तर को 4 वर्ण, यहां तक ​​कि 4 वर्ण में बढ़ रही है।

उत्तर: का कोई भी एकाधिक स्ट्रिंगबिल्डर के लिए मेमोरी आवंटन बिंदु दृश्य से कम से कम अच्छी क्षमता है, कम से कम इस 64-बिट JVM पर।

विभिन्न प्रारंभिक क्षमताओं के साथ 1000000 स्ट्रिंगबिल्डर ऑब्जेक्ट्स बनाकर परीक्षण किया गया, विभिन्न परीक्षण कार्यक्रम निष्पादन (समान प्रारंभिक ढेर राज्य के लिए) में, और पहले और बाद में ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed() प्रिंट करना।

ढेर आकारों को प्रिंट करने से यह भी पुष्टि हुई कि वास्तव में प्रत्येक StringBuilder के बफर के लिए ढेर से आवंटित राशि 8 बाइट्स का एक बहुमत है, जैसा कि जावा चार 2 बाइट लंबा है।दूसरे शब्दों में, प्रारंभिक क्षमता के साथ 1000000 उदाहरण आवंटित करना 1..4 प्रारंभिक क्षमता 5 के साथ समान संख्या में आवंटन आवंटित करने के बजाय लगभग 8 मेगाबाइट कम मेमोरी (प्रति इंस्टेंस 8 बाइट्स) लेता है ... 8।

+0

क्या आप अपनी परीक्षण प्रक्रियाओं को साझा करना चाहते हैं? - आप इस तरह के ग्रैन्युलरिटी के साथ ढेर के उपयोग को निर्धारित करने के लिए कैसे प्रबंधित करते हैं? – JimmyB

+0

मेरे पास कोड आसान नहीं है, लेकिन ढेर का उपयोग स्ट्रिंगबिल्डर प्रारंभिक क्षमता में 4 इकाइयों की हर वृद्धि को एक कदम बढ़ा देता है, फिर अगले 4 में से अगले पर कूदने से पहले, अगले 3 आकारों के लिए लगभग समान था। ** लेकिन ** यह 4 वर्ण है, जिसका मतलब 8 बाइट्स है, है ना? पूछने के लिए धन्यवाद, मैं निश्चित रूप से इसे सत्यापित करने के लिए कल फिर से परीक्षण करूँगा। – hyde

+0

तो आपने 1000000 x 4 बाइट्स के चरणों में ढेर के उपयोग में वृद्धि देखी है? - मुझे यह अनुमान लगाने की हिम्मत नहीं है कि जावा हीप स्पेस के कितने बाइट्स एक [डेटा संरचना] पर कब्जा करेंगे, न कि 'char' के लिए और किसी भी जावा प्रोग्राम में किसी भी अन्य मूल्य/प्रकार के लिए नहीं। - इसके अलावा, ढेर के * आवंटन * ग्रैन्युलरिटी के बावजूद, जीएनसी ने * रिलीज * को रिलीज करने का निर्णय लिया * स्मृति को ढीला करने के लिए अज्ञात है और किसी भी माप को प्रभावित करेगा। - यदि आप जिज्ञासा से/और किसी दिए गए जेवीएम की कुछ विशेषताओं को मापने के लिए अपना परीक्षण कर रहे हैं, तो आगे बढ़ें। - अन्यथा, ... ऊपर मेरा जवाब देखें :) – JimmyB

4

इस मामले में स्मार्ट होने की कोशिश न करें।

मैं वर्तमान में 128-16 का उपयोग कर रहा हूं, जहां 128 एक अच्छा दौर संख्या है, और घटाव आवंटन ओवरहेड के लिए है।

जावा में, यह एक जेवीएम के आंतरिक कार्यों के बारे में पूरी तरह से मनमानी धारणाओं पर आधारित है। जावा सी बाइट-संरेखण नहीं है और जैसे बिल्कुल कोई समस्या प्रोग्रामर कर सकते हैं या इसका उपयोग करने की कोशिश करनी चाहिए।

यदि आप अपने तारों की अधिकतम (संभावित) लंबाई को जानते हैं तो आप इसे प्रारंभिक आकार के लिए उपयोग कर सकते हैं। इसके अलावा, किसी भी अनुकूलन प्रयास व्यर्थ में हैं।

आप वास्तव में जानते हैं कि आपके StringBuilder के विशाल मात्रा में बहुत लंबी अवधि के लिए चारों ओर हो जाएगा (जो काफी लॉगिंग की अवधारणा से मेल नहीं खाती), और तुम सच में JVM के लिए राजी करने की कोशिश की जरूरत महसूस करते हैं स्ट्रिंग के निर्माण के बाद आप trimToSize() का उपयोग कर सकते हैं और ढेर अंतरिक्ष के कुछ बाइट्स को बचाने के लिए। लेकिन, फिर से, जब तक आपके तार मेगाबाइट बर्बाद नहीं करते हैं, तब तक आपको वास्तव में जाना चाहिए और अपने आवेदन में अन्य समस्याओं पर ध्यान देना चाहिए।

संबंधित मुद्दे