2012-03-05 16 views
21

मैंने अक्का और उसके जावा एपीआई UntypedActor का उपयोग कर एक अभिनेता प्रणाली लागू की है। इसमें, एक अभिनेता (टाइप ए) getContext().actorOf(...); का उपयोग करके, मांग पर गतिशील रूप से अन्य कलाकारों (प्रकार बी) शुरू करता है। वे बी अभिनेता कुछ गणना करेंगे जो ए को वास्तव में और अधिक परवाह नहीं है। लेकिन मैं सोच रहा हूं: क्या वे समाप्त होने पर टाइप बी के उन कलाकारों को साफ करना आवश्यक है? यदि हां, तो कैसे?अक्का: जब वे समाप्त हो जाते हैं तो गतिशील रूप से बनाए गए कलाकारों की सफाई आवश्यक है?

  • बी अभिनेताओं को getContext().stop(getSelf()) कॉल करने पर कॉल करके?
  • बी अभिनेताओं को getSelf().tell(Actors.poisonPill()); कॉल करने पर कॉल करके? [यही वह है जो मैं अब उपयोग कर रहा हूं]।
  • कुछ भी नहीं कर रहे हैं?
  • द्वारा ...?

दस्तावेज़ इस पर स्पष्ट नहीं हैं, या मैंने इसे अनदेखा कर दिया है। मेरे पास स्कैला का कुछ बुनियादी ज्ञान है, लेकिन अक्का स्रोत बिल्कुल प्रवेश स्तर की सामग्री नहीं हैं ...

उत्तर

23

जो आप वर्णन कर रहे हैं वह "अनुरोध" (ए के संदर्भ में परिभाषित) के लिए बनाए गए एकल-उद्देश्य कलाकार हैं, जो घटनाओं का अनुक्रम संभालते हैं और फिर किया जाता है, है ना? यह बिल्कुल ठीक है, और आप उन्हें बंद करने का अधिकार रखते हैं: यदि आप नहीं करते हैं, तो वे समय के साथ जमा हो जाएंगे और आप स्मृति रिसाव में भाग लेंगे। ऐसा करने का सबसे अच्छा तरीका उन संभावनाओं में से पहला है जो आप उल्लेख करते हैं (सबसे प्रत्यक्ष), लेकिन दूसरा भी ठीक है।

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

+0

http: // stackoverflow।कॉम/प्रश्न/23066264/कैन-रैपिंग-अक्का-अभिनेता-इन-क्लास-एक्टर्स-कारण-स्मृति-लीक <- संबंधित प्रश्न –

-3

डिफ़ॉल्ट रूप से अभिनेता अधिक स्मृति का उपभोग नहीं करते हैं। यदि आवेदन बाद में अभिनेता बी का उपयोग करना चाहता है, तो आप उन्हें जीवित रख सकते हैं। यदि नहीं, तो आप उन्हें poisonpill के माध्यम से बंद कर सकते हैं। जब तक आपके अभिनेता संसाधन नहीं रखते हैं, तब तक एक अभिनेता को छोड़ना ठीक होना चाहिए।

+4

लेकिन, जैसा कि रोलैंड ने बताया, अभिनेता कचरे से एकत्र नहीं होंगे और इसलिए समय => स्मृति रिसाव के साथ जमा हो जाएंगे। –

0

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

akka.actor.deployment { 
    /parent/router9 { 
    router = balancing-pool 
    nr-of-instances = 5 
    } 
} 

dispatchers पर और routing पर अधिक विस्तार के लिए दस्तावेज़ पढ़ें:

Balancing Pool Router, उदाहरण के लिए, आप एक विशेष प्रकार के शेयर के अभिनेताओं में एक ही मेलबॉक्स के पास निर्धारित करने के लिए अनुमति देता है।

0

मैं AKKA दस्तावेज से नमूना क्लस्टर एप्लिकेशन में से एक (visualvm) प्रोफाइलिंग कर रहा था और मुझे हर जीसी के दौरान प्रति अनुरोध अभिनेताओं की सफाई करने के लिए कचरा संग्रह दिखाई देता है। उपयोग के बाद अभिनेता को स्पष्ट रूप से मारने की सिफारिश पूरी तरह से समझने में असमर्थ। मेरे अभिनेता और कलाकारों को स्प्रिंग आईओसी कंटेनर द्वारा प्रबंधित किया जाता है और मैं अभिनेताओं को बनाने के लिए वसंत विस्तार में प्रत्यक्ष अभिनेता-निर्माता का उपयोग करता हूं। "एग्रीगेटर" अभिनेता को हर जीसी पर कचरा इकट्ठा हो रहा है, मैंने विजुअल वीएम में # उदाहरणों की निगरानी की।

@Component 
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 
public class StatsService extends AbstractActor { 

    private final LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this); 

    @Autowired 
    private ActorSystem actorSystem; 

    private ActorRef workerRouter; 

    @Override 
    public void preStart() throws Exception { 
     System.out.println("Creating Router" + this.getClass().getCanonicalName()); 
     workerRouter = getContext().actorOf(SPRING_PRO.get(actorSystem) 
      .props("statsWorker").withRouter(new FromConfig()), "workerRouter"); 
     super.preStart(); 
    } 

    @Override 
    public Receive createReceive() { 
     return receiveBuilder() 
      .match(StatsJob.class, job -> !job.getText().isEmpty(), job -> { 
       final String[] words = job.getText().split(" "); 
       final ActorRef replyTo = sender(); 
       final ActorRef aggregator = getContext().actorOf(SPRING_PRO.get(actorSystem) 
        .props("statsAggregator", words.length, replyTo)); 

       for (final String word : words) { 
        workerRouter.tell(new ConsistentHashableEnvelope(word, word), 
         aggregator); 
       } 
      }) 
      .build(); 
    } 
}