2009-04-20 32 views
19

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

धन्यवाद, jbu

private void startTimer() 
    { 
     Timer timer= new Timer(); 
     TimerTask timerTask= new TimerTask() 
     { 

      @Override 
      public void run() 
      { 
       System.out.println("TICK"); 
      } 
     }; 

     timer.scheduleAtFixedRate(timerTask, 
       0, 
       500); 
    } 
+0

नहीं यह भयानक होगा? यह लगभग सभी बहु-कार्य को और अधिक कठिन बना देगा। –

उत्तर

0

आप जी सी दौड़ा कैसे जानते हो? सामान्य रूप से कचरा संग्रह एक निर्धारक चीज नहीं है, और यह निश्चित रूप से विधि के दायरे से ट्रिगर नहीं होता है। यह सी ++ की तरह नहीं है जहां आप एक समारोह और विनाशकों की आग का दायरा छोड़ देते हैं। अगर जीसी इस तरह महसूस करता है तो यह उस स्मृति को इकट्ठा करने के लिए मिल जाएगा।

+1

मैंने नेटबीन के डिबगिंग मोड के माध्यम से स्पष्ट रूप से जीसी को बुलाया है। – jbu

33

Timer ऑब्जेक्ट वास्तव में पृष्ठभूमि थ्रेड में निष्पादित कार्यों को शेड्यूल करता है, ताकि पृष्ठभूमि धागा टाइमर (और टाइमरटास्क) के संदर्भ को बनाए रखे, जो दोनों को कचरा-संग्रह से रोकता है।

यहाँ डॉक्स से उपयुक्त उद्धरण है:

एक टाइमर वस्तु को पिछले लाइव संदर्भ के बाद दूर हो जाता है और सभी बकाया कार्यों को निष्पादन, पूरा कर लिया है टाइमर के कार्य निष्पादन धागा शान से समाप्त हो जाता है (और कचरा संग्रह के अधीन हो जाता है)। हालांकि, यह मनमाने ढंग से होने में लंबा समय ले सकता है। डिफ़ॉल्ट रूप से, कार्य निष्पादन थ्रेड को डेमॉन थ्रेड के रूप में नहीं चलाता है, इसलिए यह से को समाप्त करने में सक्षम है। यदि कोई कॉलर को टाइमर का कार्य निष्पादन थ्रेड को तेज़ी से समाप्त करना चाहता है, तो कॉलर को टाइमर की रद्द विधि का आह्वान करना चाहिए।

तो शर्त है कि "सभी उत्कृष्ट कार्यों ने निष्पादन पूरा कर लिया है" संतुष्ट नहीं है, और धागा कभी समाप्त नहीं होता है, इसलिए टाइमर/टाइमरटास्क कभी भी जीसीडी नहीं होता है।

+0

बिल्कुल। टाइमर के जावा डॉक्स से: "प्रत्येक टाइमर ऑब्जेक्ट के अनुरूप एक एकल पृष्ठभूमि थ्रेड है जिसका उपयोग टाइमर के सभी कार्यों को क्रमशः निष्पादित करने के लिए किया जाता है।" –

+0

हालांकि, अगर मैं टाइमर रद्द करता हूं, तो टाइमर/टाइमर टास्क अंततः जीसीएड होगा? – ptikobj

2

टाइमर संग्रहित कचरा नहीं है क्योंकि यह अभी भी चल रहा है - कुछ अन्य ऑब्जेक्ट (जैसे थ्रेड शेड्यूलर) का अभी भी इसका संदर्भ है, जो शायद scheduleAtFixedRate() के अंदर बनाया गया था।

12

क्योंकि एक टाइमर है एक background thread that continues running:

प्रत्येक टाइमर वस्तु के अनुरूप एक भी पृष्ठभूमि थ्रेड है टाइमर के कार्यों के सभी निष्पादित करने के लिए, क्रमिक रूप से प्रयोग किया जाता है। टाइमर कार्य जल्दी से पूरा करना चाहिए। यदि टाइमर कार्य को पूरा करने में अत्यधिक समय लगता है, यह टाइमर का कार्य निष्पादन धागा "hogs" करता है। इसके बदले में, बाद के कार्यों के निष्पादन में देरी हो सकती है, जो तेजी से उत्तराधिकार में ("अगर) अपमानजनक कार्य अंततः पूरा हो सकता है तो" गुच्छा "और निष्पादित हो सकता है।

चूंकि यह पृष्ठभूमि धागा है, यह तब तक जारी रहता है जब तक कि JVM बाहर निकलता है या यह बंद हो जाता है।

अद्यतन: इस पर थोड़ा और। एक "पृष्ठभूमि धागा" एक डेमॉन थ्रेड जैसा ही है - बीएसडी डिमन प्रक्रिया के साथ समानता द्वारा नामित। आप Thread पर javadocs देखते हैं, तो आपको:

मार्क्स इस सूत्र या तो एक डेमॉन धागा या एक उपयोगकर्ता के रूप में धागा। जावा वर्चुअल मशीन निकलती है जब केवल चलने वाले थ्रेड सभी डिमन धागे हैं।

जब आपका मुख्य टर्मिनेट होता है, तो सभी उपयोगकर्ता थ्रेड बंद हो जाते हैं, केवल डेमॉन थ्रेड छोड़ते हैं। JVM तब बंद हो जाता है। एक अच्छे समय के लिए - यदि मुख्य से Thread.currentThread().setDaemon(true); छोटा - कॉल करें।

अद्यतन: एएके। मेरे पास लगभग सही था। आपको टाइमर को निर्माण समय पर एक डिमन बनाना होगा। (यह परिवर्तन किया था, या मैं सिर्फ एक मस्तिष्क विफलता है?)

वैसे भी, यहाँ उदाहरण कोड है: अगर यह चले जाओ किया

import java.util.*; 

class Chatter extends TimerTask { 
    public void run(){ 
     System.err.println("Timer run."); 
    } 
} 

public class TryThread { 
    public static void main(String[] argv){ 
     // If argument is true, only runs a few times. 
     Timer t = new Timer(false); 
     t.schedule(new Chatter(), 1L, 1L); 
     return ; 
    } 
} 
+2

चार्ली के बिंदु पर जोर देने के लिए, लाइव थ्रेड कचरा कलेक्टर के लिए "रूट" ऑब्जेक्ट्स हैं। वे मरने तक कचरा नहीं होते हैं, और एकत्र नहीं किए जा सकते हैं। लाइव थ्रेड से दृढ़ता से संदर्भ-सक्षम कुछ भी कचरा नहीं है। भारित वर्ग इसी तरह से काम करते हैं। – erickson

+0

रुको, इसलिए यह टाइमर प्रोग्राम समाप्त होने के बाद भी निष्पादन जारी रख सकता है? –

+0

नहीं, क्योंकि जब प्रारंभिक समय पर सार्वजनिक स्थैतिक शून्य मुख्य रूप से लागू किया गया था, तो जेवीएम कुल मिलाकर बंद हो जाता है, जिसका मतलब पृष्ठभूमि धागे को रोकना और मारना है। यह वास्तव में जीसीएड नहीं मिलता है क्योंकि जब प्रक्रिया मर जाती है, तो सभी मेमोरी जारी होती है। –

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