haskell एक स्मृति रिसाव डीबग करना जो ढेर प्रोफाइलिंग पर प्रदर्शित नहीं होता है



memory-leaks profiling (1)

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

valgrind --leak-check=yes haskelldaemon (बेहतर यदि आप इसे डिबग जानकारी के साथ संकलित करते हैं),

या, यदि साझा लाइब्रेरी में रिसाव होता है, तो प्रयास करें

LD_PRELOAD="yourlibrary.so" valgrind your-executable

मैं एक Haskell डेमन पर काम कर रहा हूं जो JSON अनुरोधों को प्राप्त करता है और संसाधित करता है। जबकि डेमन के संचालन जटिल हैं, मुख्य संरचना को जानबूझकर सरल रखा गया है: इसकी आंतरिक स्थिति सिर्फ एक IORef जिसमें डेटा संरचना होती है और सभी थ्रेड्स इस IORef पर परमाणु संचालन करते हैं। फिर कुछ धागे हैं जो एक ट्रिगर पर मूल्य को इसके साथ कुछ करते हैं।

समस्या यह है कि डेमॉन मेमोरी लीक कर रहा है और मुझे पता नहीं चल पाया है कि क्यों। यह निश्चित रूप से अनुरोधों से संबंधित है: जब डेमॉन प्रति सेकंड कई अनुरोध प्राप्त कर रहा है, तो यह 1MB / s की तरह कुछ लीक करता है (जैसा कि लिनक्स उपकरणों द्वारा रिपोर्ट किया गया है)। मेमोरी की खपत लगातार बढ़ती है। अनुरोधों के साथ, मेमोरी की खपत स्थिर रहती है।

मुझे क्या पहेलियाँ हैं कि जीएचसी प्रोफाइलिंग में यह कोई भी नहीं दिखाता है। या तो मैं प्रोफाइलिंग पैरामीटर्स में कुछ याद कर रहा हूं, या मेमोरी कुछ और खा रही है:

+RTS -hc -xt -p साथ चलाएं:

+RTS -hr -xt -p साथ चलाएं:

इस परीक्षण के दौरान, डेमन बाद में 1GB से अधिक खपत करता है। तो प्रोफाइलिंग डेटा स्पष्ट रूप से परिमाण के आदेशों द्वारा वास्तविक खपत मेमोरी के अनुरूप नहीं है। (मैं समझता हूं कि आरटीएस, जीसी और प्रोफाइलिंग स्वयं वास्तविक मेमोरी खपत में जोड़ते हैं, लेकिन यह अंतर बहुत बड़ा है, और बढ़ती खपत के अनुरूप नहीं है।)

मैंने पहले ही rnf अंदर डेमॉन के सभी राज्य डेटा को rnf करने की कोशिश की, साथ ही JSON अनुरोधों को पार्स किया (JSON स्ट्रिंग्स के कुछ हिस्सों को कहीं न कहीं बनाए रखने के लिए), लेकिन बहुत सफलता के बिना।

किसी भी विचार या सुझाव का स्वागत किया।

अद्यतन: डेमन बिना -threaded चल रहा है, इसलिए ओएस-स्तर के थ्रेड नहीं हैं।

जीसी आँकड़े ढेर प्रोफाइल के बहुत करीब हैं जो कि लिनक्स द्वारा बताई गई संख्याओं की तुलना में हैं:

    Alloc    Copied     Live    GC    GC     TOT     TOT  Page Flts
    bytes     bytes     bytes  user  elap    user    elap
[...]
  5476616     44504   2505736  0.00  0.00   23.21  410.03    0    0  (Gen:  0)
 35499296     41624   2603032  0.00  0.00   23.26  410.25    0    0  (Gen:  0)
 51841800     46848   2701592  0.00  0.00   23.32  410.49    0    0  (Gen:  0)
 31259144     36416   2612088  0.00  0.00   23.40  410.61    0    0  (Gen:  0)
 53433632     51976   2742664  0.00  0.00   23.49  412.05    0    0  (Gen:  0)
 48142768     50928   2784744  0.00  0.00   23.54  412.49    0    0  (Gen:  0)
[...]

अद्यतन 2: मुझे समस्या का मूल मिला, मेमोरी लीक handleToFd ( यूनिक्स लाइब्रेरी के लिए इस मुद्दे को देखें) के कारण होता है। मुझे आश्चर्य है कि इस तरह के रिसाव (शायद कोड के एक विदेशी टुकड़े में होने वाली) को और अधिक प्रभावी ढंग से कैसे संभव होगा।





ghc