2013-04-09 2 views
7

나는 C++에 익숙하다. 클래스의 모든 인스턴스 (이는 사용자가 확장 할 수있는 라이브러리 클래스)의 목록을 얻으려면, 나는 일반적으로 객체에 대한 모든 참조와 정적 용기가 :자바 : 클래스의 모든 인스턴스에 대한 참조를 저장하는 방법은 무엇입니까?

#include <list> 
class CPPClass; 

class CPPClass { 
    public: 
    CPPClass() { 
     objList.push_back(this); 
    } 
    ~CPPClass() { 
     objList.remove(this); 
    } 

    private: 
    static std::list<CPPClass *> objList; 
}; 

std::list<CPPClass *> CPPClass::objList; 

을 내가 어떻게해야하는 방법 Java에서 동일합니까? 나는 몇 가지 문제가 : 여러 개의 클래스 로더가있을 수 있다는 것을 나에게 언급

  • 사람을, 그 문제
  • 자바에는 소멸자가 없다가 발생할 수 있습니다, 그래서 어떻게 참조 목록에서 제거 할 것인가?
  • 참조가 제거되지 않으면 이러한 개체가 언제 가비지 수집됩니까?
+1

[가벼운 참조] (http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html)를 개체에 저장하여 가비지 수집을 허용합니다. – GriffeyDog

답변

4

쉬운 일들 : 사용자 정의 클래스 로더와 함께 비표준 위임 패턴을 사용하지 않으면 여러 클래스 로더가 문제를 일으키지 않습니다. 그런 비표준 클래스 로더가 있다면, 앱의 다른 부분이 다른 버전의 CPPClass 클래스 (다른 ClassLoader의 각 버전)를 사용하고있는 상황을 얻을 수 있습니다. 여기에는 여러 가지 문제가 있습니다 (CPPClass에서 CPPClass으로 캐스팅 할 수 있지만 정적 컬렉션에는 영향을 미치지 않습니다). 각 CPPClass은 자체 컬렉션을 가지고 있습니다.

다음 작업 : 생성자에서 개체를 컬렉션에 추가하지 마십시오. this 참조가 생성자에서 누출되면 메모리 모델 문제가 발생할 수 있습니다. 대신 객체를 생성 한 정적 팩토리 메소드를 생성 한 다음 정적 컬렉션에 별도로 추가해야합니다. 그 콜렉션은 물론 스레드로부터 안전해야합니다.

마지막으로 핵심 질문입니다. 각 개체가 다른 개체와 같지 않은 경우 (즉, Object.equals을 재정의하지 않은 경우) 개체를 키로 사용하여 WeakHashMap을 사용할 수 있습니다. 클래스가 equals을 덮어 쓰면 WeakReference 컬렉션을 만들 수 있습니다.이 컬렉션은 편리한 시간에 삽입 (삽입시, 목록 검색 등) 할 수 있습니다. WeakReference는 GCed에서 참조되는 객체를 막지 않습니다. GC가 발생한 후에 nullget에서 반환합니다.

그러나 약간 편집 할 수있는 "솔루션"은 종종 유지 관리 문제가있는 정의되지 않은 개체 수명주기를 암시합니다.객체가 Closeable을 구현하거나 객체를 사용하여 완성되었다고 선언하는 데 사용되는 코드와 비슷한 방법을 사용하는 것이 좋습니다.

+0

나는 사용자가 원하는대로 할 수 있기 때문에'equals' 메서드에 의존 할 수 없다고 생각한다. 왜냐하면 사용자가 원하는대로 할 수 있기 때문이다. 내가 최종적으로 만들지 않는 한, 나는 너무 제한적이라고 생각한다. 'WeakHashMap'의 가치를 넣을까요? 그래서 저는 WeakArrayList와 같은 것을 가지고 있다고 생각합니다. (컨테이너에서 구현되는 것 같습니까?) 하지만 'Closeable'을 구현하는 것은 익숙하고 친숙한 프로그래밍 방식으로 돌아가는 것처럼 보이지만 이상적인 Java 솔루션이 될 것입니까? –

+1

Java 1.7을 사용하고 [try-with-resources] (http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)를 사용하려는 경우 클로저 가능 (또는 자동 닫기 가능) 구현은 확실히 가능합니다. 관용적 인 자바. 많은 JDK 클래스가 그렇게한다. InputStream, JDBC classes 등. 자신 만의 컬렉션을 사용하고 싶다면, List >에서 시작하겠다. 나는 처음부터 내 컬렉션을 구현하지 않을 것이고, JDK 컬렉션을 사용하고 수동으로 오래된 WeakReference를 제거하기 위해 수동으로 진행할 것이다. – yshavit

0

정말로 정적으로 목록을 만들 수 있습니다. 제대로 초기화 할 수도 있습니다.

List<CPPClass> objlist; 
static { 
    objlist = new List<CPPClass>(); 
} 

또는 이와 유사한 것이 좋습니다.

참조를 제거하지 않으면 가비지 수집기가 개체가 아직 사용 중이라고 가정하기 때문에 참조를 제거하지 않습니다.

소멸자와 약간 비슷해 보이는 뭔가가 있습니다 (방법 : finalize). 그러나이 메서드는 가비지 수집기에서만 호출되며 사용자가 직접 사용할 수는 없으므로 사용하지 않아도됩니다.

1

개체에 대한 참조를 저장하는 대신 WeakReference을 개체에 저장하십시오. WeakReference가 남아있는 유일한 참조 일 경우 가비지 수집기가 개체를 해제합니다.

관련 문제