2011-03-15 15 views
21

मेरे पास हैकसेल में लागू एक सर्वर प्रक्रिया है जो एक साधारण इन-मेमोरी डीबी के रूप में कार्य करती है। क्लाइंट प्रक्रियाएं तब कनेक्ट हो सकती हैं और डेटा पुनर्प्राप्त कर सकती हैं। सेवा अपेक्षा से अधिक मेमोरी का उपयोग करती है, और मैं क्यों काम करने का प्रयास कर रहा हूं।मुझे ghc heap profiler के आउटपुट की व्याख्या कैसे करनी चाहिए?

मेरे पास सबसे पुरानी मीट्रिक लिनक्स "टॉप" है। जब मैं प्रक्रिया शुरू करता हूं तो मुझे ~ 27 एमबी का "वीआईआरटी" छवि आकार दिखाई देता है। 60,000 डेटा आइटम डालने के लिए क्लाइंट चलाने के बाद, मुझे ~ 124MB का चित्र आकार दिखाई देता है।

जीसी आंकड़े (+ आरटीएस एस) पर कब्जा करने की प्रक्रिया चल रहा है, मैं शुरू में देख

Alloc Copied  Live GC GC  TOT  TOT Page Flts 
bytes  bytes  bytes user elap user elap 
28296  8388  9172 0.00 0.00 0.00 0.32 0 0 (Gen: 1) 

और 60k आइटम मैं जीना बाइट्स

... 
    532940  14964 63672180 0.00 0.00 23.50 31.95 0 0 (Gen: 0) 
    532316  7704 63668672 0.00 0.00 23.50 31.95 0 0 (Gen: 0) 
    530512  9648 63677028 0.00 0.00 23.50 31.95 0 0 (Gen: 0) 
    531936  10796 63686488 0.00 0.00 23.51 31.96 0 0 (Gen: 0) 
    423260 10047016 63680532 0.03 0.03 23.53 31.99 0 0 (Gen: 1) 
    531864  6996 63693396 0.00 0.00 23.55 32.01 0 0 (Gen: 0) 
    531852  9160 63703536 0.00 0.00 23.55 32.01 0 0 (Gen: 0) 
    531888  9572 63711876 0.00 0.00 23.55 32.01 0 0 (Gen: 0) 
    531928  9716 63720128 0.00 0.00 23.55 32.01 0 0 (Gen: 0) 
    531856  9640 63728052 0.00 0.00 23.55 32.02 0 0 (Gen: 0) 
    529632  9280 63735824 0.00 0.00 23.56 32.02 0 0 (Gen: 0) 
    527948  8304 63742524 0.00 0.00 23.56 32.02 0 0 (Gen: 0) 
    528248  7152 63749180 0.00 0.00 23.56 32.02 0 0 (Gen: 0) 
    528240  6384 63756176 0.00 0.00 23.56 32.02 0 0 (Gen: 0) 
    341100 10050336 63731152 0.03 0.03 23.58 32.35 0 0 (Gen: 1) 
    5080 10049728 63705868 0.03 0.03 23.61 32.70 0 0 (Gen: 1) 

यह करने के लिए सुचारू रूप से हो जाना देख जोड़ने पर ऐसा लगता है कि ढेर में ~ 63 एमबी लाइव डेटा है। जब आप स्टैक स्पेस, कोड स्पेस, जीसी ओवरहेड इत्यादि में जोड़ते हैं, तब तक यह शीर्ष से संख्याओं के अनुरूप हो सकता है।

इसलिए मैंने इस 63 एमबी को बनाने के लिए हेप प्रोफाइलर का उपयोग करने का प्रयास किया। परिणाम उलझन में हैं। के साथ "+ आरटीएस -h" चल रहा है, और उत्पन्न अश्वशक्ति फ़ाइल को देखते हुए पिछले और सबसे बड़ा स्नैपशॉट है:

containers-0.3.0.0:Data.Map.Bin 1820400 
bytestring-0.9.1.7:Data.ByteString.Internal.PS 1336160 
main:KV.Store.Memory.KeyTree 831972 
main:KV.Types.KF_1 750328 
base:GHC.ForeignPtr.PlainPtr 534464 
base:Data.Maybe.Just 494832 
THUNK 587140 

स्नैपशॉट में अन्य नंबरों के सभी इस तुलना में काफी छोटा है।

enter image description here

क्यों इस लाइव बाइट्स के साथ असंगत के रूप में जीसी आंकड़ों में दिखाई गई है: इन देता ~ 6MB के रूप में शिखर स्मृति के उपयोग, के रूप में चार्ट उत्पादन में परिलक्षित जोड़ा जा रहा है? यह देख रहा है कि मेरे डेटा संरचनाओं को 63 एमबी की आवश्यकता हो सकती है, और प्रोफाइलर का कहना है कि वे नहीं हैं। स्मृति कहाँ जा रही है?

इस पर किसी भी सुझाव या पॉइंटर्स के लिए धन्यवाद।

टिम

+2

आपके द्वारा शामिल किया गया imgur.com छवि लिंक टूटा हुआ प्रतीत होता है। – Heatsink

+0

यदि आप टूलबार में StackOverflow की "छवि" लिंक के माध्यम से एक छवि शामिल करते हैं (या Ctrl-G टाइप करें), तो इसे तोड़ने की संभावना कम होती है। – ShreevatsaR

उत्तर

1

आप का उपयोग करना चाहिए, उदाहरण के लिए, क्या हो रहा है की एक ग्राफिकल दृश्य प्राप्त करने के hp2ps। कच्चे एचपी फ़ाइल को देखना मुश्किल है।

+2

धन्यवाद - मैंने एचपी 2पीएस का उपयोग किया था। एक नए स्टैक ओवरफ़्लो उपयोगकर्ताओं के रूप में, मुझे परिणामी छवि पेस्ट करने की अनुमति नहीं थी :-(। लेकिन एचपी फ़ाइल से ऊपर चिपकने वाली रेखाएं एचपी 2 एस द्वारा दिखाए गए ग्राफिकल दृश्य को दर्शाती हैं। – timbod

+0

@ टिंबोड: अब आपके पास पर्याप्त प्रतिनिधि शामिल होना चाहिए छवि; शायद यह करने में मददगार होगा। –

1

डिफ़ॉल्ट रूप से प्रोफ़ाइल में सब कुछ शामिल नहीं है, उदाहरण के लिए धागे और ढेर। +RTS -xT के साथ प्रयास करें।

+0

मैंने '+ RTS -h -S -xt' के साथ प्रयास किया। यह अभी भी मुझे लाइव बाइट्स गिनती (63 एमबी) में प्रोफ़ाइल के रूप में दिखाए गए शीर्ष डेटा बनाम काफी अलग परिणाम देता है (लगभग 6 एमबी)। इसलिए मुझे अभी भी नुकसान हुआ है कि स्मृति का उपयोग कैसे किया जा रहा है। – timbod

3

मेरे पास एक सिद्धांत है। मेरा सिद्धांत यह है कि आपका प्रोग्राम ByteStrings जैसे कुछ का उपयोग कर रहा है। मेरा सिद्धांत यह है कि ByteStrings की मुख्य सामग्री malloc एटीड है, इसलिए वे प्रोफाइलिंग के दौरान प्रदर्शित नहीं होते हैं। इस प्रकार आप प्रोफाइलिंग ग्राफ पर दिखाई देने वाले ढेर की सबसे बड़ी सामग्री के बिना ढेर से बाहर निकल सकते हैं।

मामलों को और भी खराब बनाने के लिए, जब आप ByteStrings की सबस्ट्रिंग लेते हैं, तो वे डिफ़ॉल्ट रूप से पॉइंटर को स्मृति के मूल आवंटित ब्लॉक में बनाए रखते हैं। इसलिए यदि आप केवल ByteString के छोटे फ्रेजमेंट को स्टोर करने का प्रयास कर रहे हैं, तो आप मूल रूप से आवंटित ByteString को पूरा कर सकते हैं और यह आपके ढेर प्रोफाइल पर दिखाई नहीं देगा।

यह मेरा सिद्धांत वैसे भी है। मुझे इस बारे में पर्याप्त तथ्य नहीं पता कि जीएचसी के ढेर प्रोफाइलर कैसे काम करते हैं और न ही ByteStrings को निश्चित रूप से जानने के लिए लागू किया जाता है।शायद कोई और मेरे सिद्धांत में झुकाव और पुष्टि या विवाद कर सकता है।

संपादित 2: tibbe नोट करता है कि ByteString एस द्वारा उपयोग किए गए बफर पिन किए गए हैं। इसलिए यदि आप बहुत छोटे Bytestring एस आवंटित/मुक्त कर रहे हैं, तो आप अपने ढेर को विभाजित कर सकते हैं जिसका मतलब है कि आप इसे आधे से अधिक उपयोग के साथ उपयोग करने योग्य ढेर से बाहर चलाते हैं।

संपादित करें: जाफ्फाकेक मुझे बताता है कि कभी-कभी ढेर प्रोफाइलर बाइटस्ट्रिंग द्वारा आवंटित स्मृति प्रदर्शित नहीं करेगा।

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