2012-03-01 14 views
6

मेरे पास multithreading के साथ निष्पादित करने की आवश्यकता है।निष्पादक सेवा का उपयोग करते समय स्मृति का प्रबंधन कैसे करें?

मैं ExecutorService का उपयोग Callable objects के बहुत सारे प्रस्तुत करने के लिए, और प्रत्येक Callable object कुछ resource जो क्रियान्वित करने के लिए आवश्यक है शामिल हैं।

समस्या

इन कार्यों इतने सारे कि Callable objectsExecutorService को प्रस्तुत की बहुत अधिक स्मृति पर कब्जा तो heap समाप्त हो रहा है कर रहे हैं।

मैं जानना चाहता हूं कि JVM इन Callable objects के लिए जगह कब जारी करता है?

क्या यह कार्य पूरा होने के तुरंत बाद ऐसा करता है और मैं ExecutorService के लिए उपयोग की गई मेमोरी का प्रबंधन कैसे कर सकता हूं?

मैं ExecutorService पर सबमिशन को नियंत्रित करना चाहता हूं, उदाहरण के लिए, जब स्मृति पर्याप्त नहीं है तो सबमिशन को कुछ कार्यों को पूरा करने और मुक्त स्थान का उपयोग करने से रोकें। यह हो सकता है?


पूरा कोड बहुत जटिल है, मैं अपने कोड का मुख्य फ्रेम संलग्न करूंगा।

public class MyCallable implements Callable<Result> { 

    ... // Some members 

    public MyCallable(...) { 
    ... 
    } 

    @Override 
    public Result call() throws Exception { 
    ... // Doing the task 
    } 
} 

class MyFutureTask extends FutureTask<Result> { 

    ... // Some members 

    public MyFutureTask(...) { 
    super(new MyCallable(...)); 
    } 

    @Override 
    public void done() { 
    Result result = get(); 
    ... // Something to do immediately after the task is done 
    } 
} 

// Here is the code to add tasks 
ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); 
while (...) { 
    ... // Reading some data from files 
    executor.submit(new MatchFutureTask(...)); 
} 
executor.shutdown(); 
+0

आपकी समस्या का उत्तर दिया जा सकता है आप एक कोड स्निपेट शामिल हैं। आप किस प्रकार की एक्जिक्यूटर सेवा का उपयोग कर रहे हैं? कई अर्थ क्या हैं (यानी कितने लोग हैं)? –

+0

पीएस: मुझे एहसास है कि आप वास्तव में एक स्मृति रिसाव समस्या का सामना कर रहे हैं (मुझे लगता है कि आपके ऐप के किसी अन्य भाग में आप अपने कॉलबल्स के संदर्भ धारण कर रहे हैं) और निष्पादक सेवा समस्या नहीं। –

+0

@AlexCalugarescu मैं निष्पादक सेवा बनाने के लिए execors.newFixedThreadPool() का उपयोग करता हूं, इसलिए यह ThreadPoolExecutor होना चाहिए। और "कई" का अर्थ है, मूल पाठ फ़ाइल 3 जीबी से अधिक है, मैंने इसे पढ़ा और कॉलबल्स में स्टोर करने के लिए कुछ ऑब्जेक्ट्स में गुप्त किया, इसलिए मुझे लगता है कि यह वास्तव में बहुत अधिक है। – Auguste

उत्तर

3

विधि Runtime.getRuntime().freeMemory() आपको बताएगी कि जेवीएम की कितनी मुफ्त मेमोरी है। आप ThreadFactory कार्यान्वयन लिख सकते हैं जो एक नया धागा बनाने से पहले इस मान को जांचता है।

+0

कोई समस्या नहीं है जिसका सामना कर रहा हूं लेकिन शानदार उत्तर +1। – Shahzeb

6

यदि आप एक्जिक्यूटर्स सेवा का उपयोग कर रहे हैं, तो आपको कन्स्ट्रक्टर में ब्लॉकिंगक्यूयू पास करना होगा, है ना? मुझे लगता है कि आप थ्रेडपूलएक्सएटर का उपयोग कर रहे हैं। एक निश्चित क्षमता के साथ एक ArrayBlockingQueue का उपयोग करें, और ThreadPoolExecutor.CallerRunsPolicy को ThreadPoolExecutor कन्स्ट्रक्टर को पास करें। यदि आप maxPoolSize को कुछ उचित मान पर सेट करते हैं तो यह आपकी सबमिशन दर को प्रभावी ढंग से सीमित कर देगा।

अपने पहले प्रश्न का उत्तर देने के लिए, वीएम "कुछ समय बाद" स्मृति जारी करेगा, वस्तुओं के किसी भी संदर्भ में अब कोई संदर्भ नहीं है। यदि कॉल करने योग्य राज्य के मामले में आत्मनिर्भर है, तो इसे निष्पादित करने के बाद, वीएम को आपको स्मृति त्रुटि से बाहर करने से पहले कचरा इकट्ठा करना चाहिए।

+0

ठीक है, मैं निष्पादक सेवा बनाने के लिए केवल execors.newFixedThreadPool() का उपयोग करता हूं, इसलिए मैंने ब्लॉकिंगक्यूयू पास नहीं किया। BlockingQueue क्या करता है? – Auguste

+0

एक ब्लॉकिंगक्यूयू केवल निष्पादक में विशिष्ट संख्या में कार्यों को कतारबद्ध करने की अनुमति देगा। निष्पादक। NewewixedTreadPool() असीमित कार्यों की अनुमति देगा। – brettw

+2

मुझे लगता है कि मैं इसे हल करता हूं।मैं अपने द्वारा ThreadPoolExecutor ऑब्जेक्ट बनाने के लिए बदलता हूं, जो वास्तव में प्रतीक्षा कार्य कतार के आकार को नियंत्रित कर सकता है। आपका बहुत बहुत धन्यवाद! – Auguste

2

था कि 30% की Executors.newCachedThreadPool() कम स्मृति का उपयोग - 60%

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