2012-03-05 31 views
21

Tôi đã triển khai hệ thống diễn viên sử dụng Akka và Java API UntypedActor của nó. Trong đó, một diễn viên (loại A) bắt đầu các diễn viên khác (loại B) theo yêu cầu động, sử dụng getContext().actorOf(...);. Những diễn viên B sẽ làm một số tính toán mà A không thực sự quan tâm nữa. Nhưng tôi tự hỏi: có cần phải dọn sạch những diễn viên kiểu B này khi họ đã hoàn thành không? Nếu vậy, làm thế nào?Akka: Dọn dẹp các diễn viên được tạo động cần thiết khi họ hoàn thành?

  • Bằng cách để diễn viên B gọi getContext().stop(getSelf()) khi chúng hoàn tất?
  • Bằng cách để diễn viên B gọi getSelf().tell(Actors.poisonPill()); khi họ hoàn tất? [đây là những gì tôi đang sử dụng bây giờ].
  • Bằng cách không làm gì?
  • Bởi ...?

Tài liệu không rõ ràng về điều này hoặc tôi đã bỏ qua nó. Tôi có một số kiến ​​thức cơ bản về Scala, nhưng các nguồn Akka không chính xác là mục nhập cấp ...

Trả lời

23

Những gì bạn mô tả là các tác nhân mục đích được tạo cho mỗi "yêu cầu" (được xác định trong ngữ cảnh A), xử lý một chuỗi các sự kiện và sau đó được thực hiện, phải không? Điều đó hoàn toàn ổn, và bạn có quyền đóng cửa chúng: nếu không, chúng sẽ tích luỹ theo thời gian và bạn sẽ bị rò rỉ bộ nhớ. Cách tốt nhất để làm điều này là khả năng đầu tiên bạn đề cập (trực tiếp nhất), nhưng điều thứ hai cũng không sao.

Một chút nền: diễn viên được đăng ký trong cha mẹ của họ để có thể nhận dạng được (ví dụ như cần thiết trong điều khiển từ xa nhưng cũng ở những nơi khác) và đăng ký này khiến họ không bị thu gom rác. OTOH, mỗi phụ huynh có quyền truy cập vào các trẻ em được tạo ra, do đó không có sự chấm dứt tự động (nghĩa là bởi Akka) có ý nghĩa, thay vào đó yêu cầu tắt mã rõ ràng trong mã người dùng.

+0

http: // stackoverflow.com/questions/23066264/can-wrapping-akka-diễn viên-trong-lớp-diễn viên-gây ra-bộ nhớ-rò rỉ <- Câu hỏi liên quan –

-3

Các tác nhân theo mặc định không tiêu thụ nhiều bộ nhớ. Nếu ứng dụng dự định sử dụng diễn viên b sau này, bạn có thể giữ chúng hoạt động. Nếu không, bạn có thể tắt chúng thông qua ngộ độc. Miễn là các diễn viên của bạn không nắm giữ tài nguyên, để lại một diễn viên nên ổn.

+4

Nhưng, như Roland đã chỉ ra, diễn viên sẽ không bị thu gom rác và do đó sẽ tích luỹ theo thời gian => rò rỉ bộ nhớ. –

0

Ngoài câu trả lời của Roland Kuhn, thay vì tạo một diễn viên mới cho mọi yêu cầu, bạn có thể tạo một nhóm diễn viên được xác định trước chia sẻ cùng một điều phối viên hoặc bạn có thể sử dụng bộ định tuyến phân phối yêu cầu tới một nhóm diễn viên.

Các Balancing Pool Router, ví dụ, cho phép bạn có một tập cố định của các diễn viên của một loại cổ phiếu đặc biệt là cùng một hộp thư:

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

Đọc tài liệu trên dispatchers và trên routing để xem chi tiết hơn nữa.

0

Tôi đã lược tả (visualvm) một trong các ứng dụng cụm mẫu từ tài liệu AKKA và tôi thấy bộ sưu tập rác dọn sạch mỗi tác nhân yêu cầu trong mỗi GC. Không thể hoàn toàn hiểu được đề nghị giết chết diễn viên một cách rõ ràng sau khi sử dụng. Diễn viên và diễn viên của tôi được quản lý bởi container SPRING IOC và tôi sử dụng phần mở rộng mùa xuân trong diễn viên-sản xuất trực tiếp để tạo ra các diễn viên. "aggregator" diễn viên đang nhận được rác thu thập trên mỗi GC, tôi đã giám sát số lượng các cá thể trong VM trực quan.

@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(); 
    } 
} 
Các vấn đề liên quan