2013-01-03 2 views
3

해결하려고하는 디자인 문제가 있습니다. 요약하면 finalize()을 사용하여 해당 객체에만 관련된 리소스를 private static 개까지 풀어 낼 수 있으며 해당 객체가 존재하는 한 오랫동안 사용할 수 있습니까?데코레이터 패턴을 사용하여 finalize() 사용

  1. 내가

  2. X입니다 작성하지 않은 유형 (X)를 캡슐화하는 데코레이터 패턴을 사용하고 있습니다 : 세부

    여기

    첫 번째 제약은 ...에 따라 final 그래서 하위 클래스 화는 문제가되지 않습니다.

  3. 내가 래퍼의 방법이 언제든지 반환 것, x()을 말하는 X instance

  4. 기본 x() 이유는 래퍼 유형이 기존의 API 년대와 상호 교환 호환 할 필요가 있다는 것입니다 그 X 매개 변수를

  5. 을 기대 래퍼는 매개 변수로 X 인스턴스를 사용하는 생성자가 있습니다. 그런 다음 캡슐화 된 X 개체를 인스턴스로 설정합니다.

문제 :

내가 래퍼에서 일부 기능/데이터를 추가 할

하지만이 그것을 유지했다. 이 말은 래퍼가 X으로 래핑되지 않았을 때 코드의 다른 지점에서 래퍼로 '다시 래핑'될 수 있다는 것을 의미합니다.이 래스터가 이전에 배치되어 있지 않더라도 여분의 데이터가 복원됩니다. 기초가되는 X.

내 생각이 지금까지 : 나는 키가 유일 X ID입니다 래퍼 클래스의 정적지도를 생성하고 값이 일부 구조에서이 추가 데이터 인 경우

, 그때 나는 내부를 검색 할 수 있습니다 rewrap(X x) 방법을 보자.

래퍼 또는 X 개체를지도의 키로 사용하지 않으므로지도에서 명시 적으로 제거되지 않는 한 GC를 중지하므로 고유 한 해시 코드를 사용합니다.

이것은 원칙적으로 괜찮은 것처럼 보이지만 정적 맵에서이 여분의 데이터를 삭제해야 할 때가 있습니다.

finalize(){ 
    map.remove(wrapperKey); 
} 

여기 내 정당화 우리 모두는 (마무리에 의존 알고 ...의)는 일반적으로 리소스를 해제하는 나쁜 생각이지만, 여기에 자원 문제 :이 경우 우리는 마무리()의 구현을 허용 할 수 있습니다 물체와 직접 관련이있다. 외부 리소스에 대한 참조가 없으므로 래퍼 객체 자체가 GC 될 때까지 이러한 내부 리소스가 필요합니다. 그러면 리소스 매핑을 삭제합니다.

메모리 누수가 발생하기 때문에 최악의 시나리오는 중복되는 정적 매핑을 삭제하는 것에 대해 걱정할 필요가 없습니다.

나는 기존의 API와 이전 버전과의 호환성이 기능을 달성하고 유지하기 위해 다른 방법을 생각할 수 없다

:

public void foo(Wrapper wrapper){ 
    bar(wrapper.x()); 
} 
public void bar(X instance){...} 

그래서 문제의를 대체 할 수있는 다른 방법이나 의견?

많은 감사

편집 : 추가 연구 생각 후에는 명시 적으로 Wrapper.x에게 액세스를 필요로 할 때마다 호출하면 나는 유사한 상황 weak references

답변

0

에 대한 주요 후보가 될 수있다이 질문을 업데이트 X 인스턴스에서 Wrapper에 정리 메서드를 추가하고 Wrapper 개체를 제거하기 전에이를 명시 적으로 호출 할 수 없습니까?

클린업 메소드가 finalize에서 호출되어 명시 적으로 호출되지 않은 경우 클린업 할 수 있습니다. 래퍼가 잘못 사용되면 메모리 누수를 줄일 수있는 기회가 많기 때문에 이렇게하면 두 가지 장점이 있습니다.

void someRandomMethod() { 
    Wrapper someWrapperINeed = new Wrapper(new X(blah, blah blah)); 
    foo(someWrapperINeed); 
    someWrapperINeed.clean(); 

    // Instead of foo(new Wrapper(new X(blah, blah, blah)); 
} 

// Or foo can call clean if the wrapper will never be needed after its invocation 
void foo(Wrapper w) { 
    bar(w.x()); 
    w.clean(); 
} 

편집 : 코드 샘플 추가!

+0

나는 약간의 명확성이 부족했기 때문에 질문을 편집했습니다. 죄송합니다. 추가 데이터는 X 인스턴스와 직접 연관되므로 언 래핑 된 X 인스턴스가 나중에 다시 래핑되는 경우 보존해야합니다. 따라서 x()에 여분의 데이터를 처리 할 수 ​​없습니다. – ComethTheNerd

+1

wrapperKey는 X 인스턴스와 관련이 있습니까? 그래서 당신은 여분의 데이터를 검색하고 X를 아는 것에서 Wrapper 객체를 다시 만들 수 있습니까? 이 경우 X 객체를 키로 직접 사용하지 않는 이유는 무엇입니까? 그리고 Wrapper의 finalize 메소드에서 추가 데이터를 어떻게 삭제할 수 있습니까? 그런 다음 래퍼를 다시 만들기 전에 데이터가 손실 될 가능성이 높습니다. – Sardtok

+0

그게 중요한 포인트입니다. 래퍼는 일회용이며 언제든지 재 작성되므로 키는 X에 직접 관련되어 있어야합니다. 이 여분의 데이터를 삭제하는 것은 래퍼가 마지막으로 X를 래핑했는지 여부를 알 수 없기 때문에이 경우 X의 finalize에서 수행해야합니다. Hmmm ... 같은 것을 달성하기위한 대안적인 접근에 대한 어떤 생각? – ComethTheNerd

관련 문제