2014-11-03 7 views
22

परिचयमैं GHCi रिहाई स्मृति

निम्नलिखित कोड, पता चलता है कि जब runhaskell हास्केल कचरा कलेक्टर का उपयोग कर स्मृति विज्ञप्ति जब a नहीं रह गया है प्रयोग किया जाता है कैसे कर सकते हैं। इसके परिणामस्वरूप कोर डंप में परिणाम a जारी करते हैं - एक उद्देश्य के लिए, व्यवहार का निरीक्षण करने के लिए - a को nullFunPtr को अंतिमकर्ता के रूप में मिला है।

module Main where 

import Foreign.Ptr 
import Foreign.ForeignPtr 


main :: IO() 
main = do 
    a <- newForeignPtr nullFunPtr nullPtr 
    putStrLn "Hello World" 

समस्या

जब GHCi यह स्मृति जारी नहीं करता है में एक ही चल रहा है। मैं ghci को अब उपयोग किए जाने वाले चर को रिलीज़ करने के लिए कैसे मजबूर कर सकता हूं?

$ ghci 
> import Foreign.Ptr 
> import Foreign.ForeignPtr 
> import System.Mem 
> a <- newForeignPtr nullFunPtr nullPtr 
> a <- return() -- rebinding variable a to show gc that I'm no longer using it 
> performGC 
> -- did not crash - GC didn't release memory 
> ^D 
Leaving GHCi. 
[1] 4396 segmentation fault (core dumped) ghci 

मेमोरी बाहर निकलने पर जारी किया गया था, लेकिन यह मेरे लिए बहुत देर हो चुकी है। मैं जीएचसीआई का विस्तार कर रहा हूं और इसे अन्य उद्देश्यों के लिए उपयोग कर रहा हूं और मुझे पहले से ही स्मृति को रिलीज करने की आवश्यकता है - मांग पर या जितनी जल्दी हो सके उतनी जल्दी होगी।

मुझे पता है कि मैं finalizeForeignPtr पर कॉल कर सकता हूं, लेकिन मैं केवल डीबग उद्देश्यों के लिए foreignPtr का उपयोग कर रहा हूं। मैं पिछले उदाहरण में सामान्य रूप से a कैसे जारी कर सकता हूं?

यदि ghci प्रॉम्प्ट के साथ ऐसा करने की कोई संभावना नहीं है, तो मैं ghci कोड भी संशोधित कर सकता हूं। हो सकता है कि मैं a को modyfing ghci Interactive Context या DynFlags द्वारा रिलीज़ कर सकता हूं? अब तक मुझे अपने रीसेसर के साथ कोई भाग्य नहीं मिला है।

+1

क्या आप सुनिश्चित हैं कि स्मृति जारी नहीं है? मुझे नहीं लगता कि एक गारंटी है कि एक चर वैरिएबल होने पर फाइनल तुरंत चलते हैं। –

+1

इसके बजाए, मैंने बड़े सरणी के साथ समान परीक्षण किए और 'ekg' के साथ इसकी निगरानी की। कुछ भी जारी नहीं किया गया था। – remdezx

+0

'()' के पुनर्मूल्यांकन के बाद एकत्रित कचरा क्यों होना चाहिए? Ghci कैसे पता चलेगा (एक तरह के आईओ monad के अंदर से) की आवश्यकता नहीं होगी? –

उत्तर

9

कोड हम पाते हैं कि मूल्य डेटा प्रकार PersistentLinkerState है, जो एक ClosureEnv है के क्षेत्र closure_env में संग्रहीत किया जाता है, यानी HValue रों को नाम से एक मानचित्रण के माध्यम से ट्रेसिंग। Linker.hs में प्रासंगिक समारोह

extendLinkEnv :: [(Name,HValue)] -> IO() 
-- Automatically discards shadowed bindings 
extendLinkEnv new_bindings = 
    modifyPLS_ $ \pls -> 
    let new_closure_env = extendClosureEnv (closure_env pls) new_bindings 
    in return pls{ closure_env = new_closure_env } 

है और हालांकि टिप्पणी इंगित करता है कि यह छाया बंधन को दूर करना चाहिए, यह नहीं है, कम से कम नहीं जिस तरह से आप यह चाहते हैं।

कारण है, क्योंकि एंड्रयूसी सही तरीके से लिखता है: हालांकि दोनों चरों में एक ही स्रोत कोड नाम होता है, वे संकलक के लिए अलग होते हैं (उनके पास Unique संलग्न होता है)। हम कुछ ट्रेसिंग ऊपर कार्य करने के लिए जोड़ने के बाद इस का पालन कर सकते हैं: इस बिंदु अपने जीसी समस्या का समाधान करना चाहिए पर एक ही स्रोत-नाम के साथ

*GHCiGC> a <- newForeignPtr nullFunPtr nullPtr 
extendLinkEnv [a_azp] 
*GHCiGC> a <- return() 
extendLinkEnv [a_aF0] 
*GHCiGC> performGC 
extendLinkEnv [it_aFL] 

निकाला जा रहा है बाइंडिंग, लेकिन मैं संकलक अच्छी तरह से क्या यह बताने के लिए पर्याप्त जानकारी नहीं है और तोड़ देगा। मेरा सुझाव है कि आप टिकट खोलें, उम्मीद है कि कोई जान जाएगा। बनाम मूल्य बंधन पर

भ्रम

टिप्पणियों में बाइंडिंग और मूल्यों के बारे में कुछ भ्रम की स्थिति हो रहा है।इस कोड पर विचार करें:

> a <- return something 
> b <- return somethingelse 
> a <- return (b+b) 
> b <- return anewthing 

वर्तमान कार्यान्वयन के साथ, ढेर `

  • something
  • somethingelse
  • एक thunk (+) ऑपरेटर और somethingelse
  • anewthing संदर्भित शामिल होंगे।

इसके अलावा दुभाषिया के पर्यावरण में सभी चार ढेर मूल्यों के संदर्भ हैं, इसलिए जीसी'ड कुछ भी नहीं हो सकता है।

क्या ठीक ही उम्मीद remdezx कि GHCi something और somethingelse करने के लिए संदर्भ ड्रॉप होता है। यह बदले में, रन टाइम सिस्टम कचरे को something एकत्र करने की अनुमति देगा (हम कोई और संदर्भ नहीं मानते हैं)। जीएचसीआई अभी भी थंक का संदर्भ देता है, जो बदले में somethingelse संदर्भित करता है, इसलिए यह कचरा एकत्रित नहीं होगा।

स्पष्ट रूप से प्रश्न बहुत कार्यान्वयन विशिष्ट था, और इसी प्रकार यह जवाब है :-)

+2

एक बाध्यकारी छायांकित किया जा सकता है लेकिन अभी भी अप्रत्यक्ष रूप से संदर्भित किया गया है: 'a <- वापसी 1; एफ <- वापसी (कॉन्स ए); एक <- वापसी(); $ एफ अपरिभाषित प्रिंट करें। –

+0

उस समय में अधिक समय खोदने के लिए धन्यवाद! मैंने पहले से ही इसी तरह की बग की रिपोर्ट की है (https://ghc.haskell.org/trac/ghc/ticket/9765) लेकिन मैं एक और रिपोर्ट करूंगा और समस्या को अलग कर दूंगा। – remdezx

+2

@ विल्स नेस: बाध्यकारी को और संदर्भित नहीं किया जा सकता है। बेशक '' मूल्य '' बंद हो सकता है, लेकिन इसे बंद करके सुरक्षित रूप से संदर्भित किया जाता है, "नामित चीजों के पर्यावरण" को पकड़ने के लिए कोई आवश्यकता नहीं है! –

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