2013-03-05 6 views
2

어떻게 안드로이드 가비지 컬렉터가 단편에 의해 유지되는 데이터로 작동하는지 궁금합니다 (인스턴스 유지).안드로이드 : 단편 인스턴스 메모리 관리를 유지

나는이 같은 클래스 hirarchy있는 경우 : 조각이 내용을 볼 orientation 변화에 그 recreatd됩니다

class MyFragment extends Fragment { 

     private DataManager dataManager; 

     public MyFragment(){ 
      setRetainInstance(true); 
     } 


     public void onCreate(){ 
      if (dataManager == null) 
      dataManager = new DataManager(); 

      dataManager.setView(this); 
     } 


     public void onCreateView(){ 
      // display the data of the dataManager 
     } 


     public void onStop(){ 
      dataManager.setView(null); 
     } 
    } 


class DataManager implements DataChangedListener { 

    private MyFragment view; 
    private Data data; 


    public DataManager(){ 

      data.setDataChangedListener(this); 

    } 


    public void setView(MyFragment v){ 
      this.view = v;   
     } 

} 


class Data { 

     public void setDataChangedListener(DataChangedListener l){ 
      this.listener = l; 
     } 
} 

그래서 내가하고 싶은 것은

을. 그러나 기본 데이터 ( DataManager 및 데이터)는 다시로드하지 않아야합니다. DataManager은 변경 사항을 위해 데이터 객체를 수신하고,이 변경 사항을 UI로 전달합니다 ( Fragment). Fragment은 (재) DataManager에 "첨부"됩니다.

지금까지 그렇게 좋았습니다. 그것은 나에게 좋은 솔루션과 잘 구성된 것 같습니다. 기본적으로 어떤 종류의 Model-View-Presenter 패턴입니다.

하지만 안드로이드가 DataManager 및 데이터 객체를 수집하기 위해 가비지 수집기를 실행하면 궁금합니다.

Activity가 MyFragment 인 것으로 가정합니다.

하지만 메모리에 어떤 변화가 생기면 앱 사용자가 다른 활동으로 이동할 때 완전히 다른 것을 표시합니다.

데이터에 DataManager이라는 참조가 있고 그 반대의 경우도 있으므로 데이터가 "영원히"메모리에 보관됩니다. 맞습니까? 가비지 수집기는 장치가 메모리가 부족한 경우에만이 둘을 제거합니다. 그러나 나는이 두 객체가 자동으로 가비지 수집 된 처음 두 데이터 객체가되지는 않을 것이라고 생각합니다. 어떤 종류의 "메모리 교착 상태"가 있다고 생각합니다.

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

+0

이러한 누출을 방지하려면 WeakReference를 사용할 수 있습니다. http://weblogs.java.net/blog/2006/05/04/understanding-weak-references –

답변

0

에 관한 가비지 콜렉터 :

나는 내가 아는 한, 가비지 컬렉터는 알려진 객체에서 시작하여 모든 개체 경우, 오브젝트 트리 아래 "탐색", 여기에 몇 가지 개념을 잘못 그러나 수 그 나무에 없다면, 그것은 수집 될 것입니다.

예를 들어 액티비티에서 가져온 통계와 어댑터에 대한 몇 가지 뷰에 대한 참조가 있고 FragmentManager에 FragmentManager는 3 개의 프래그먼트, 몇 개의 데이터 객체에 대한 프래그먼트 등을 참조합니다. 에.

Object_A가 Object_B를 참조하고 Object_B를 Object_B로 참조하지만 다른 하나가 Object_A 또는 Object_B를 참조하지 않으면 그 둘에 키스 할 수 있습니다.

제안 : 보통

전체 setRetainInstance(true); 거래를 단순화하기 위해, (추상적 그 의무 아니라, 기억,하지만 쉽게 삶을 이해할 수 있도록 않고) 나 자신에 대한 규칙을 만들 : 내가 원하는 경우 그건/데이터를 유지해야하며 setRetainInstance을 사용하여 하나의 조각에보기가 없음을 의미합니다. 다시 말하면, 나는 그것을 onCreateView으로 바꾸지 않고 그 트랜잭션을 단순한 add(mFrag, MyFrag.TAG);으로 레이아웃에 배치하지 않는다는 의미입니다.

당신은 모든 뷰가 필요할 때 다시 만들어집니다 당신은 항상 그 방법으로 당신은 당신의 데이터가 수 없음을 알고, 다시 GC 거래에 getFragmentManager().findFragmentByTag(MyFrag.TAG);

그리고를 사용하여 데이터에 액세스 할 수 있는지 알고 있기 때문에 단순화

FragmentManager에 안전하게 보관되어 있기 때문에 GCed되었습니다.

좋은 계획 같습니까? 어떻게 생각하니?

편집 :

또한 제안 :

이 DataFragment에있는 모든보기를 참조, 또는 활동, 또는 컨텍스트를 유지하지 않습니다. 긴 생명체는 모든 활동을 유지하면서 그 참조를 유지하면 안되며 엄청난 메모리 누출입니다.

+0

감사합니다! 조각 코드에 코드를 더 추가했습니다. 내가 원하는 것은 데이터를 잃어 버리지 않고 다시로드하지 않고 방향 변경을 처리하는 것입니다. 그러나 내가 활동을 끝내면 다른 활동을 시작하여 데이터가 GC에 의해 수집 될 수 있도록하고 싶습니다. 그래서 프래그먼트를 보관하는 Activity를 떠날 때 DataManager와 Data 사이에 참조가 있습니다. 다른 참조. 위에서 설명한 것처럼 GCed 될 수 있습니다. 당신은 그것에 대해 확신합니까, 아니면 추측입니까? setRetainInstance()를 어떻게 다루는 지 알려주는 단어입니다. 이해가 안됩니다. 설명해 주시겠습니까? – sockeqwe

+0

\\ sdk \ extras \ android \ support \ samples \ Support4Demos \ src \ com \ example \ android \ supportv4 \ app \ FragmentRetainInstanceSupport.Java에서 예제를 확인하십시오. 그게 무슨 뜻이야. 작동하는 조각을 확인하고 데이터에 "onCreateView"가 없도록하십시오. – Budius

관련 문제