2011-03-29 4 views
5

나는 Hessian/hessdroid를 통해 서버에서 데이터를 검색하는 서버/클라이언트 응용 프로그램이 있습니다. 데이터는 다른 HashMaps 및 바이트 배열로 저장된 이미지를 포함하는 HashMaps와 매우 복잡합니다. 데이터를 완벽하게 표시 할 수 있습니다.HashMap 비 직렬화

서버를 항상 쿼리하지는 않지만 데이터 구조를 캐시로 사용하고 있습니다. 이 데이터 객체는 앱을 닫을 때 ObjectOutputStream을 사용하여 SD 카드에 저장합니다. 다시 시작하면 ObjectInputStream을 사용하여 메모리로 다시 읽습니다.

SD 카드에서 데이터를 읽은 후에 만 ​​앱에 문제가 있습니다. 힙이 ~ 17메가바이트 응용 프로그램 충돌에 성장하면

INFO/dalvikvm-heap(4150): Grow heap (frag case) to 10.775MB for 281173-byte allocation 

: 다른 메시지 사이

DEBUG/dalvikvm(4150): GetFieldID: unable to find field Ljava/util/HashMap;.loadFactor:F 

이의 : 로그 캣은 나에게 다음과 같은 출력 (100 번)를 제공합니다.

HashMap 직렬화에 관한 여러 스레드를 읽었을 때 아키텍처간에 직렬화 할 때 버그가있는 것 같았지만 나에게는 Hessian을 통한 데이터 전송이 완벽하게 작동하고 디스크에서 HashMaps를 읽을 때만 설명한 문제가있었습니다.

아이디어가 있으십니까?

+0

데이터를로드하고 직렬화 해제 한 코드를 게시 할 수 있습니까? –

+0

로그 고양이와 얼 (Earl)이 언급 한 소스 코드의 전체 덤프를 추가하십시오. 여기에 언급 한 내용에서 메모리 부족 문제와 같은 냄새가납니다 (http://code.google.com/p/android/issues/detail?id=14869). –

답변

2

문제는 사이버 - 몽크가 언급 한대로 HashMap 직렬화와 직접적인 관련이 없습니다. 실제로 Android 또는 HashMap 구현에 버그가 있습니다.하지만 앱이 다운되는 이유는 아닙니다.

이제 앱에서 이미지를 적게 사용하여 문제를 해결했습니다. 나는 예를 들어 갤러리를 가지고있어서 플리퍼 (flipper)에서 한 이미지에서 다른 이미지로 스 와이프하여 모든 이미지를 한 번에로드 할 수있었습니다. 일정량의 이미지에서 힙 공간이 충분하지 않습니다.

내 해결책은 모든 디코딩 된 이미지를 한 번에 보지 않기 위해서입니다.

1) 바이너리를로드 한 이미지가 큰 아니기 때문에 문제가되지 않습니다)

2) 안되 (메모리에 바이너리 이미지 데이터를 잡고이 같은 일

오기 ' Flipper의 뷰를 생성 할 때 이미지 데이터를 ImageViews에 저장합니다.

3) 이진 이미지 데이터를 표시된 ImageView로 설정하십시오. 투명 색상의 자원을 설정하여 표시되지 않습니다

5) "언로드"를 ImageViews) 다음과 더 나은 사용자 경험을위한 마지막 이미지 뷰의

4) 유지 바이너리 이미지 데이터.

Here's 일부 코드 :

// initialize the viewFlipper by creating blank views 
for (ComponentImageDto listElement : images) { 
    LinearLayout view = renderView(); 
    flipper.addView(view); 
} 
showImage(flipper.getCurrentView()); 

renderView()는 단지 내가 바이너리 데이터를 설정 한 다음/이전 이미지를 표시하는 몇 가지 방법을 썼다 이미지 뷰 그런

을 포함하는있는 LinearLayout을 반환

private void showNextElement() { 
    // show next flipper view 
    flipper.showNext(); 

    // get current view 
    int displayedChild = flipper.getDisplayedChild(); 
    View currentView = flipper.getCurrentView(); 

    // load the binary data 
    showImage(currentView); 

    // get the next to last view index (if keeping max. 3 images at a time in memory) 
    int otherChild = (displayedChild - 2); 
    if (otherChild < 0) { 
     otherChild = otherChild + flipper.getChildCount(); 
    } 

    // .. and remove it 
    removeImage(flipper.getChildAt(otherChild)); 
} 

private void showPreviousElement() { 
    flipper.showPrevious(); 
    int displayedChild = flipper.getDisplayedChild(); 
    View currentView = flipper.getCurrentView(); 
    showImage(currentView); 
    setTitle((CharSequence) currentView.getTag()); 
    int otherChild = (displayedChild + 2) % flipper.getChildCount(); 
    removeImage(flipper.getChildAt(otherChild)); 
} 

private void removeImage(View view) { 
    ImageView imageView = (ImageView) view.findViewById(R.id.gallery_image); 
    if (imageView != null) { 
     imageView.setImageResource(R.color.transparent); 
     System.gc(); 
    } 
} 

private void showImage(View view) { 
    ImageView imageView = (ImageView) view.findViewById(R.id.gallery_image); 
    if (imageView != null) { 
     bm = BitmapHelper.decodeByteArray(images.get(flipper.getDisplayedChild()).getImage().getBinaryObject()); 
     imageView.setImageBitmap(bm); 
    } 
} 

furtherly 메모리가 미안 내가 유래에서 발견 BitmapHelper 클래스의 일부 코드를 사용하여 처리 향상을 위해 메모리를 절약하는 데 도움이 다음 이미지 뷰에 크기를 줄여서 이미지를 만듭니다.