2013-08-16 5 views
6

मेरे पास एसटी के अंदर एक गणना है जो डेटा के माध्यम से स्मृति आवंटित करता है। वेक्टर.इनबॉक्स। मटेबल। वेक्टर कभी पढ़ा या लिखा नहीं जाता है, न ही किसी भी संदर्भ को runST (मेरे ज्ञान के सर्वोत्तम) के बाहर रखा जाता है। मेरी समस्या यह है कि जब मैं अपने एसटी गणना कई बार चलाता हूं, तो मुझे कभी-कभी वेक्टर के लिए मेमोरी रखने की प्रतीत होती है।हास्केल: एसटी/जीसी से स्मृति एकत्र नहीं कर रहा है?

आवंटन आंकड़े:

5,435,386,768 bytes allocated in the heap 
    5,313,968 bytes copied during GC 
    134,364,780 bytes maximum residency (14 sample(s)) 
    3,160,340 bytes maximum slop 
      518 MB total memory in use (0 MB lost due to fragmentation) 

यहाँ मैं अपने गणना और एक 128MB वेक्टर के लिए विभिन्न मूल्यों के साथ runST 20x फोन (फिर से - अप्रयुक्त, लौट आए या अनुसूचित जनजाति के बाहर संदर्भित नहीं)। अधिकतम निवास अच्छी लगती है, मूल रूप से बस मेरे वेक्टर प्लस कुछ अन्य एमबी के कुछ एमबी। लेकिन कुल स्मृति उपयोग इंगित करता है कि मेरे पास एक ही समय में सक्रिय वेक्टर की चार प्रतियां हैं। वेक्टर के आकार के साथ पूरी तरह से यह तराजू, 256 एमबी के लिए हमें उम्मीद के अनुसार 1030 एमबी मिलती है।

1 जीबी वेक्टर का उपयोग स्मृति से बाहर चलाता है (4x1GB + ओवरहेड> 32 बिट)। मुझे समझ में नहीं आ रहा है कि क्यों आरटीएस केवल जीसी के बजाए अप्रत्याशित, अप्रतिबंधित स्मृति रखता है, कम से कम उस बिंदु पर जहां आवंटन अन्यथा असफल हो जाता है।

+ आरटीएस एस के साथ चल रहा है निम्नलिखित का पता चलता है:

Alloc Copied  Live GC GC  TOT  TOT Page Flts 
    bytes  bytes  bytes user elap user elap 
134940616  13056 134353540 0.00 0.00 0.09 0.19 0 0 (Gen: 1) 
    583416  6756 134347504 0.00 0.00 0.09 0.19 0 0 (Gen: 0) 
    518020  17396 134349640 0.00 0.00 0.09 0.19 0 0 (Gen: 1) 
    521104  13032 134359988 0.00 0.00 0.09 0.19 0 0 (Gen: 0) 
    520972  1344 134360752 0.00 0.00 0.09 0.19 0 0 (Gen: 0) 
    521100  828 134360684 0.00 0.00 0.10 0.19 0 0 (Gen: 0) 
    520812  592 134360528 0.00 0.00 0.10 0.19 0 0 (Gen: 0) 
    520936  1344 134361324 0.00 0.00 0.10 0.19 0 0 (Gen: 0) 
    520788  1480 134361476 0.00 0.00 0.10 0.20 0 0 (Gen: 0) 
134438548  5964 268673908 0.00 0.00 0.19 0.38 0 0 (Gen: 0) 
    586300  3084 268667168 0.00 0.00 0.19 0.38 0 0 (Gen: 0) 
    517840  952 268666340 0.00 0.00 0.19 0.38 0 0 (Gen: 0) 
    520920  544 268666164 0.00 0.00 0.19 0.38 0 0 (Gen: 0) 
    520780  428 268666048 0.00 0.00 0.19 0.38 0 0 (Gen: 0) 
    520820  2908 268668524 0.00 0.00 0.19 0.38 0 0 (Gen: 0) 
    520732  1788 268668636 0.00 0.00 0.19 0.39 0 0 (Gen: 0) 
    521076  564 268668492 0.00 0.00 0.19 0.39 0 0 (Gen: 0) 
    520532  712 268668640 0.00 0.00 0.19 0.39 0 0 (Gen: 0) 
    520764  956 268668884 0.00 0.00 0.19 0.39 0 0 (Gen: 0) 
    520816  420 268668348 0.00 0.00 0.20 0.39 0 0 (Gen: 0) 
    520948  1332 268669260 0.00 0.00 0.20 0.39 0 0 (Gen: 0) 
    520784  616 268668544 0.00 0.00 0.20 0.39 0 0 (Gen: 0) 
    521416  836 268668764 0.00 0.00 0.20 0.39 0 0 (Gen: 0) 
    520488  1240 268669168 0.00 0.00 0.20 0.40 0 0 (Gen: 0) 
    520824  1608 268669536 0.00 0.00 0.20 0.40 0 0 (Gen: 0) 
    520688  1276 268669204 0.00 0.00 0.20 0.40 0 0 (Gen: 0) 
    520252  1332 268669260 0.00 0.00 0.20 0.40 0 0 (Gen: 0) 
    520672  1000 268668928 0.00 0.00 0.20 0.40 0 0 (Gen: 0) 
134553500  5640 402973292 0.00 0.00 0.29 0.58 0 0 (Gen: 0) 
    586776  2644 402966160 0.00 0.00 0.29 0.58 0 0 (Gen: 0) 
    518064  26784 134342772 0.00 0.00 0.29 0.58 0 0 (Gen: 1) 
    520828  3120 134343528 0.00 0.00 0.29 0.59 0 0 (Gen: 0) 
    521108  756 134342668 0.00 0.00 0.30 0.59 0 0 (Gen: 0) 

यहाँ ऐसा लगता है हम 'जी बाइट्स' से अधिक ~ 128MB की है।

+RTS -hy प्रोफ़ाइल मूल रूप से बस का कहना है कि हम आवंटित 128MB:

http://imageshack.us/a/img69/7765/45q8.png

मैं एक सरल कार्यक्रम में इस व्यवहार से उत्पन्न होने की कोशिश की, लेकिन फिर भी अनुसूचित जनजाति, एक रीडर वेक्टर युक्त, एक ही साथ सटीक सेटअप नकल के साथ मोनड/प्रोग्राम स्ट्रक्चर इत्यादि। सरल परीक्षण कार्यक्रम यह नहीं दिखाता है। मेरे बड़े कार्यक्रम को सरल बनाना स्पष्ट रूप से पूरी तरह से असंबंधित कोड को हटाते समय व्यवहार अंततः बंद हो जाता है।

Qs:

  • Am मैं वास्तव में 20 में से 4 बार के आसपास इस सदिश रखने?
  • यदि हां, तो मैं वास्तव में +RTS -Hy और maximum residency दावा के बाद से कैसे कहूं कि मैं नहीं हूं, और इस व्यवहार को रोकने के लिए मैं क्या कर सकता हूं?
  • यदि नहीं, तो हास्केल क्यों नहीं कर रहा है और पता स्थान/स्मृति से बाहर चला रहा है, और मैं इस व्यवहार को रोकने के लिए क्या कर सकता हूं?

धन्यवाद!

+2

मेमोरी आमतौर पर अधिकतम निवास या दो बार उपयोग की जाती है, आवंटन और संग्रह पैटर्न पर निर्भर करती है। तो 518 एमबी की कुल मेमोरी स्वयं ही खतरनाक नहीं है। जीएचसी को यह कहने का प्रयास करें कि उदाहरण के लिए '$ ./foo + RTS -M256M' उपयोग करने के लिए केवल इतना स्मृति है, इसे पहले एकत्र करने के लिए मजबूर करने के लिए। लेकिन "न ही रनस्ट के बाहर इसे किसी भी संदर्भ में रखा गया है" असत्य हो सकता है, आप वास्तव में एक रिसाव हो सकता है। अगर ऐसा होता है तो कोड को देखने की आवश्यकता होगी। –

+0

@DanielFischer 518MB ~ 4x है, हालांकि। 1 जीबी वेक्टर के साथ आउट-ऑफ-मेमोरी क्रैश नहीं इंगित करेगा कि जीएचसी * स्मृति को एकत्र नहीं कर सकता है? + आरटीएस-एम 256 एम 'ढेर थका हुआ' के साथ विफल रहता है। वेक्टर बनाया जाता है, एक रीडर पर्यावरण के अंदर रखा जाता है, यही वह है। कुछ और नहीं, एसटी/रीडर छोड़ने के बाद किसी भी संदर्भ को लीक करने से बचने के लिए मैं और क्या कर सकता हूं। जैसे मैंने कहा, मैं इस समस्या को एक सरल कार्यक्रम में पुन: उत्पन्न नहीं कर सकता। यह बल्कि यादृच्छिक लगता है। – NBFGRTW

+0

खैर, 4 × सही/गलत आवंटन पैटर्न दिया जा सकता है। आउट-ऑफ-मेमोरी क्रैश यह इंगित कर सकता है कि जीएचसी को यह नहीं पता कि अब इसे एकत्र करना चाहिए, लेकिन यह देखते हुए कि '-M256M' कारण "ढेर थका हुआ" है, ऐसा लगता है कि जानवर के पास कुछ संदर्भ है। –

उत्तर

2

मुझे संदेह है कि यह जीएचसी और/या आरटीएस में एक बग है।

सबसे पहले, मुझे विश्वास है कि कोई वास्तविक स्थान रिसाव या ऐसा कुछ भी नहीं है।

कारण:

  • वेक्टर कहीं भी इस्तेमाल कभी नहीं किया है। पढ़ा नहीं, लिखा नहीं, संदर्भित नहीं है। इसे चलाने के बाद इसे एकत्र किया जाना चाहिए। यहां तक ​​कि जब एसटी गणना एक एकल इंट देता है जिसे तुरंत मूल्यांकन करने के लिए मुद्रित किया जाता है, तो स्मृति समस्या अभी भी मौजूद है। उस डेटा का कोई संदर्भ नहीं है।
  • प्रत्येक प्रोफाइलिंग मोड आरटीएस ऑफ़र हिंसक समझौते में है कि मेरे पास वास्तव में आवंटित/संदर्भित एक ही वेक्टर के लायक स्मृति से अधिक नहीं है। प्रत्येक आंकड़े और सुंदर चार्ट कहते हैं कि।

अब, दिलचस्प दिलचस्प है। यदि मैं अपने कार्य के प्रत्येक भाग के बाद System.Mem.performGC पर कॉल करके मैन्युअल रूप से जीसी को मजबूर करता हूं, तो समस्या पूरी तरह से दूर हो जाती है।

तो हमारे पास ऐसा मामला है जहां रनटाइम में जीबी की स्मृति है जो (demonstrably!) जीसी द्वारा पुनः दावा किया जा सकता है और यहां तक ​​कि अपनी खुद की सांख्यिकी के अनुसार किसी और द्वारा नहीं आयोजित किया जाता है। अपने मेमोरी पूल से बाहर होने पर रनटाइम एकत्र नहीं होता है, लेकिन इसके बजाय ओएस को अधिक मेमोरी के लिए पूछता है। और जब भी वह अंततः विफल हो जाता है, तब भी रनटाइम एकत्र नहीं करता है (जो स्मृति की जीबी की याद दिलाता है, लेकिन इसके बजाय प्रोग्राम को आउट-ऑफ-मेमोरी त्रुटि के साथ समाप्त करने का विकल्प चुनता है।

मैं हास्केल, जीएचसी या जीसी पर कोई विशेषज्ञ नहीं हूं। लेकिन यह मेरे लिए बहुत टूटा हुआ लग रहा है। मैं इसे एक बग के रूप में रिपोर्ट करूंगा।

+0

क्या आप कभी भी इसकी रिपोर्ट करें? – jberryman

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