2011-09-07 5 views
2

Android 용 Mono 응용 프로그램에서 메모리 누수를 찾는 데 문제가 있습니다. 나중에 설명 할 모든 모범 사례를 따르고 있다고 생각하지만 일관되고 재현 가능한 활동 반복 횟수 후에 OutOfMemoryError를 계속 유지합니다.Android 용 모노 - OutOfMemoryError

에뮬레이터에서 ddms을 사용하면 ViewFlipper이 다음 페이지로 넘길 때마다 내 앱이 약 200 개의 여분 "데이터 개체"와 약 30kB의 메모리를 소비한다는 것을 알 수 있습니다. 우리는 다른 자원도 소비하고 있지만 훨씬 낮은 속도로 진행됩니다.

ViewFlipper 약간 비 독점적으로 사용합니다. 그것은 한 방향으로 만 플립, 이미 표시되어있는 View의 제거 : described in this blog post 나는 우리가 사용하고있는 View들에 대한 참조의 Dispose()에 큰 관심을 가지고있다

while (flipper.ChildCount > 2) 
{ 
    flipper.RemoveViewAt(0); 
} 

을. 나는 (자동 범위의 끝에서 객체를 Dispose()) 모든 UI 구성 요소에 대한 종교적 using를 사용 :이 메모리 누수에 어떤 영향을 미칠 것 같지 않습니다

using (TextView questionView = header.FindViewById<TextView>(Resource.Id.question)) 
{ 
    questionView.Text = question.Text; 
} 

. Bitmap (일반적으로 크기가 20KB 미만인 PNG 파일)을로드 할 때마다 동일한 패턴을 사용합니다.이 패턴은 자주 사용합니다.

업데이트 : 내가 확장 방법을 사용하여 비트 맵을로드가 :

public static Bitmap BitmapFromAsset(this Context context, String asset) 
{ 
    Bitmap bitmap; 
    using (Stream stream = context.Assets.Open(asset)) 
    { 
     bitmap = BitmapFactory.DecodeStream(stream); 
     stream.Close(); 
    } 
    return bitmap; 
} 

비트 맵은 다음과 같이 사용됩니다

using (Bitmap b = this.BitmapFromAsset(path)) 
{ 
    imageView.SetImageBitmap(b); 
} 

는 업데이트 : 아란 아래에서 알 수 있듯이, 내가 위임을 사용 이 코드는 내 코드에서 일반적인 패턴입니다.

using (View button = FindViewById(Resource.Id.button)) 
{ 
    button.Click += delegate 
    { 
     // do something 
    }; 
} 

View을 제거 할 때 핸들러를 제거하도록 변경하면 누출에 차이가 없습니다.

업데이트 : Bug posted with Xamarin with example project.

답변

1

필자와 약간 비슷하고 매우 어려운 이슈 (WP7에서는 알비톨)가 있었지만 여전히 그 모든 것이 닷넷과 관련이있다. 밖으로 나갔다면 범위를 벗어나지 않은 다른 클래스의 GameScreen 클래스에 일부 대리인을 연결했습니다. 뷰 인스턴스에 대한 참조를 잃을뿐만 아니라 - 연결된 모든 이벤트 및 위임을 수행하고 있는지 확인하십시오.

+0

예, 대리인을 사용하여 다른 '보기'에 연결하고 있습니다. 그래서 델리게이트를 사용하는 모든 이벤트 핸들러 또는 모든 이벤트 핸들러를 제거해야합니다. 당신이 이것을 가지고 있다고하자 :'using (Button b = FindViewById

+0

방정식에서'Click' 핸들러를 제거해도 위와 같은 방식으로 메모리가 계속 누출됩니다. –

+0

흥미 롭습니다. 대리자가 익명 메소드이고 뷰 인스턴스 자체의 범위에 있기 때문에 특정 예제가 누출되지는 않습니다. 나는 나 자신도 잘 설명하지 않았다고 생각한다. 내 GameScreen이 내 Engine 클래스의 이벤트 (또는 델리게이트)에 메서드 중 하나를 연결했기 때문에 내 게임이 누출되었습니다. 엔진은 첨부 된 이벤트를 통해 GameScreen 클래스에 대한 참조를 보유하고있었습니다.누설과 관련이있는 것은 아닙니다 : ( – Aranda