2012-05-09 2 views
10

के साथ आवंटित स्मृति को मुक्त करने के रूप में लाइब्रेरी दस्तावेज़ newCString के साथ बनाए गए free फ़ंक्शन से मुक्त होना चाहिए। मैं उम्मीद कर रहा हूं कि जब CString बनाया गया है तो यह कुछ मेमोरी लेगा और जब इसे free के साथ रिलीज़ किया जाएगा तो स्मृति उपयोग नीचे जाएगा, लेकिन ऐसा नहीं हुआ! यहाँ उदाहरण कोड है:newCString

module Main where 

import Foreign 
import Foreign.C.String 
import System.IO 

wait = do 
    putStr "Press enter" >> hFlush stdout 
    _ <- getLine 
    return() 

main = do 
    let s = concat $ replicate 1000000 ['0'..'9'] 
    cs <- newCString s 
    cs `seq` wait -- (1) 

    free cs 
    wait -- (2) 

जब कार्यक्रम में (1), htop कार्यक्रम से पता चला कि स्मृति के उपयोग 410M के आसपास कहीं है बंद कर दिया - यह ठीक है। मैं एंटर दबाता हूं और प्रोग्राम लाइन (2) पर रुक जाता है, लेकिन cs के बावजूद मेमोरी उपयोग अभी भी 410 एम है free डी!

यह कैसे संभव है? सी में लिखे गए इसी तरह के कार्यक्रम के रूप में व्यवहार करना चाहिए। मुझे यहां क्या समझ नहीं आ रहा है?

+1

जीएचसी का कौन सा संस्करण आप उपयोग कर रहे हैं? ओएस में मेमोरी वापस करने की क्षमता पिछले साल जीएचसी में ही जुड़ी थी। –

+0

'ghc --version' outputs 'शानदार ग्लासगो हास्केल संकलन प्रणाली, संस्करण 7.4.1' –

उत्तर

8

समस्या यह है कि free सिर्फ कचरा कलेक्टर को इंगित करता है कि अब यह स्ट्रिंग एकत्र कर सकता है। यह वास्तव में कचरा कलेक्टर को चलाने के लिए मजबूर नहीं करता है - यह सिर्फ इंगित करता है कि सीएसटींग अब कचरा है। ढेर दबाव हेरिस्टिक्स के आधार पर यह तय करने के लिए अभी भी जीसी तक है।

आप कर सकते हैं बल सीधे free करने के लिए कॉल, जो तुरंत 5M या तो करने के लिए स्मृति कम कर देता है के बाद performGC को फोन करके एक प्रमुख संग्रह।

उदा। इस कार्यक्रम:

import Foreign 
import Foreign.C.String 
import System.IO 
import System.Mem 

wait = do 
    putStr "Press enter" >> hFlush stdout 
    _ <- getLine 
    return() 

main = do 
    let s = concat $ replicate 1000000 ['0'..'9'] 
    cs <- newCString s 
    cs `seq` wait -- (1) 

    free cs 
    performGC 
    wait -- (2) 

व्यवहार करती है, उम्मीद के रूप में निम्नलिखित स्मृति प्रोफाइल के साथ - पहले लाल डॉट performGC करने के लिए कॉल, तुरंत स्ट्रिंग deallocating है। कार्यक्रम तब तक 5 एमएम तक समाप्त हो जाता है जब तक कि समाप्त नहीं हो जाता है।

enter image description here

+0

बहुत बहुत धन्यवाद। मुझे नहीं पता था कि ghc में 'malloc' /' free' इस तरह से काम करता है। मैंने 'performGC' की कोशिश की और यह वास्तव में काम करता है। खैर, यह सवाल तब उठ गया जब मैं परीक्षण कर रहा था कि कुछ सी पुस्तकालयों के काम के लिए मेरी बाध्यता कितनी अच्छी तरह से है। मैंने उन्हें बड़ी संख्या में सी तारों के साथ परीक्षण किया और यह पता चला कि स्मृति जारी नहीं हो रहा था। ऐसा लगता है कि यह रहस्य अब हल हो गया है) –

+2

मुझे लगता है कि मैं आपके साक्ष्य के साथ बहस नहीं कर सकता कि 'performGC' वास्तव में काम करता है, लेकिन यह वही है जो मैंने माना था जब तक मैं गया और [स्रोत] (http: // हैकेज.haskell.org/packages/archive/base/4.5.0.0/doc/html/src/Foreign-Marshal-Alloc.html#free) - ऐसा लगता है कि 'फ्री' वास्तव में सी फ़ंक्शन को मुफ्त में कॉल करता है () '। यह जीसी के साथ कैसे बातचीत करता है? –

+2

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

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

  • कोई संबंधित समस्या नहीं^_^