2009-11-11 2 views
3

GC 가능 언어에서 관찰자가 주제 이벤트에 가입하면 실제로 피사체에 관찰자 참조가 있습니다.관찰 패턴이 GC 문제를 일으킬 때

따라서 관찰자를 삭제하기 전에 먼저 구독 취소해야합니다. 다른 말로하면, 여전히 주제에 의해 참조 되었기 때문에 결코 가비지 수집되지 않습니다.

  1. 수동
  2. 약한 참조 유엔 - 구독 :

    은 일반적으로 3 개 솔루션이 있습니다.

두 가지 모두 다른 문제를 일으 킵니다.

대개는 관찰자 패턴을 사용하고 싶지 않지만 대체로 찾을 수는 없습니다.

내 말은,이 패턴은 자연스럽게 당신이 더 나은 것을 거의 찾을 수 없다는 것을 의미합니다.

당신은 어떻게 생각하십니까?

+0

관찰자를 떨어 뜨리는 것은 무엇입니까? 관찰자가 떨어 뜨렸다 고 말 했나요? –

답변

1

이 시나리오에서는 Java에서 finalize()을 사용할 수 있습니다. finalize()은 외부 시스템에 영향을주기 때문에 (DB 연결과 같은) 리소스를 해제 할 때 나쁜 생각입니다. 귀하의 경우, 옵저버를 설치 한 객체는 응용 프로그램의 런타임 중에 GC로 처리되고 finalize()이 호출되며 관찰자의 가입을 취소 할 수 있습니다.

정확히 원하는 것은 아니지만 누군가는 "지금 탈퇴해도 괜찮습니다"라고 결정해야합니다. 그것은 피사체가 없어지면 발생합니다 (그러나 모든 피사체를 이미 죽여야합니다). 또는 관찰자를 설치 한 피사체.

앱이 예기치 않게 종료되는 경우 음,이 경우에는 finalize()이 호출되지 않을 수도 있습니다.

+2

아니. 너는 그것을 얻지 못한다. 관찰자의 참조가 있기 때문에 관찰자의 fianlize()는 결코 트리거되지 않습니다. – ablmf

+0

좋아,하지만 누군가가 그 관찰자를 추가했습니다. 객체가 사라지면 관측자는 더 이상 필요하지 않으므로이 코드를 "설치 프로그램"의 종료 자에 넣을 수 있습니다. –

+0

패턴이 필요하다면 설치 프로그램을 인수로 인수를 관측자에게 전달하면 관측자가 설치자에게 "파괴"옵저버로 설치해야합니다 ... 만약 내가 드리프트를 받으면 ... –

0

관찰자를 삭제하려면 구독 취소를 통해 게시자에게 알리십시오. 그렇지 않으면 이벤트를 보내려고 시도하며 작성 방법에 따라 앱이 다운되거나 오류가 자동으로 무시되거나 오류가 제거 될 수 있습니다. 관찰자. 그러나, 뭔가를 열면 닫으십시오. 구독하는 경우 구독을 취소하십시오.

귀하가 탈퇴하지 않는다는 사실은 나쁜 디자인 인 IMO입니다. 빈약 한 구현을 위해 패턴을 비난하지 마십시오.

는 관찰자 패턴은 잘 작동하지만 몇 가지 문제를 완화하려는 경우, 당신은 구현을 위해 AOP를 사용할 수 있습니다 http://www.cin.ufpe.br/~sugarloafplop/final_articles/20_ObserverAspects.pdf

0

가 얼마나 자주 몇 가지 관찰 것은 변화를 계산 객체의 경우를 생각해 볼 수 있습니다. 객체에 대한 두 가지 유형의 참조가 있습니다. (1) 개수에 관심이있는 엔티티의 참조. (2) 관찰 할 수있는 것에 의해 사용되는 것으로, 실제로 카운트에 관심이 없지만 그것을 업데이트 할 필요가있는 것. 카운트에 관심이있는 엔티티는 개체에 대한 참조를 보유해야하며, 개체를 참조하는 개체에 대한 참조를 보유합니다. 카운트를 업데이트해야하지만 실제로 관심이없는 엔티티는 두 번째 객체에 대한 참조 만 보유해야합니다.

첫 번째 객체에 파이널 라이저가있는 경우 객체가 범위를 벗어날 때 실행됩니다. 이는 두 번째 객체의 탈퇴를 유발할 수 있지만 직접 탈퇴하지 않아야합니다.탈퇴에는 아마도 잠금을 획득해야 할 것이고 finalizers는 잠금을 기다리지 말아야합니다. 대신 첫 번째 객체의 finalizer는 Interlocked.CompareExchange를 사용하여 유지 관리되는 연결된 목록에 해당 객체를 추가해야하며 일부 다른 스레드는 구독 취소가 필요한 객체에 대해 해당 목록을 주기적으로 폴링해야합니다.

참고 : btw : 첫 번째 개체가 두 번째 개체에 대한 참조를 보유하고있는 경우 첫 번째 개체의 종료자가 실행될 때 후자는 이 보장되지만 특정 상태가 될 수는 없습니다. 정리 스레드는 구독 취소 이외의 작업을 시도해서는 안됩니다.

관련 문제