2013-03-19 3 views
6

많은 테스트 방법을 사용하여 Activity에 대한 단위 테스트를 만들려고합니다. 그러나 약 31 번의 테스트 후에 힙에 메모리가 부족하기 때문에 응용 프로그램이 종료됩니다.큰 Android 활동 단위 테스트가 실패하는 이유는 무엇입니까?

1152 E SurfaceFlinger createSurface() failed, generateId = -12 
1152 W WindowManager OutOfResourcesException creating surface 
1152 I WindowManager Out of memory for surface! Looking for leaks... 
1152 W WindowManager No leaked surfaces; killing applicatons! 
1152 W ActivityManager Killing processes Free memory at adjustment 1 

나는 문제를 찾기 위해 40 개의 동일한 간단한 테스트 케이스로 단위 테스트를 만들었습니다. 그러나 GC가 테스트 중에 메모리를 정리하기에 충분히 빠르지 않은 것처럼 느낍니다.

package my.app; 

import android.os.Debug; 
import android.test.ActivityInstrumentationTestCase2; 
import android.util.Log; 

public class leakTest extends 
     ActivityInstrumentationTestCase2<TestActivityAndroid> { 

    String TAG = "leakTest"; 

    TestActivityAndroid mActivity = null; 

    public leakTest() { 
     super(TestActivityAndroid.class); 
    } 

    protected void setUp() throws Exception { 
     super.setUp(); 
     setActivityInitialTouchMode(false); 

     mActivity = getActivity(); 
    } 

    protected void tearDown() throws Exception { 
     super.tearDown(); 
    } 

    private void printHeapSize() { 
     Log.e(TAG, 
       "NativeHeapAllocatedSize = " 
         + Debug.getNativeHeapAllocatedSize()); 
     Log.e(TAG, "NativeHeapFreeSize = " + Debug.getNativeHeapFreeSize()); 
     Log.e(TAG, "NativeHeapSIZE = " + Debug.getNativeHeapSize()); 
    } 

    public void test_1() { 
     assertNotNull(mActivity); 
    } 

    public void test_2() { 
     assertNotNull(mActivity); 
    } 

    public void test_3() { 
     assertNotNull(mActivity); 
    } 

    public void test_4() { 
     assertNotNull(mActivity); 
    } 

    public void test_5() { 
     assertNotNull(mActivity); 
    } 

    public void test_6() { 
     assertNotNull(mActivity); 
    } 

    public void test_7() { 
     assertNotNull(mActivity); 
    } 

    public void test_8() { 
     assertNotNull(mActivity); 
    } 

    public void test_9() { 
     assertNotNull(mActivity); 
    } 

    public void test_10() { 
     assertNotNull(mActivity); 
    } 

    public void test_11() { 
     assertNotNull(mActivity); 
    } 

    public void test_12() { 
     assertNotNull(mActivity); 
    } 

    public void test_13() { 
     assertNotNull(mActivity); 
    } 

    public void test_14() { 
     assertNotNull(mActivity); 
    } 

    public void test_15() { 
     assertNotNull(mActivity); 
    } 

    public void test_16() { 
     assertNotNull(mActivity); 
    } 

    public void test_17() { 
     assertNotNull(mActivity); 
    } 

    public void test_18() { 
     assertNotNull(mActivity); 
    } 

    public void test_19() { 
     assertNotNull(mActivity); 
    } 

    public void test_20() { 
     assertNotNull(mActivity); 
    } 

    public void test_21() { 
     assertNotNull(mActivity); 
    } 

    public void test_22() { 
     assertNotNull(mActivity); 
    } 

    public void test_23() { 
     assertNotNull(mActivity); 
    } 

    public void test_24() { 
     assertNotNull(mActivity); 
    } 

    public void test_25() { 
     assertNotNull(mActivity); 
    } 

    public void test_26() { 
     assertNotNull(mActivity); 
    } 

    public void test_27() { 
     assertNotNull(mActivity); 
    } 

    public void test_28() { 
     assertNotNull(mActivity); 
    } 

    public void test_29() { 
     assertNotNull(mActivity); 
    } 

    public void test_30() { 
     assertNotNull(mActivity); 
    } 

    public void test_31() { 
     assertNotNull(mActivity); 
    } 

    public void test_32() { 
     assertNotNull(mActivity); 
    } 

    public void test_33() { 
     assertNotNull(mActivity); 
    } 

    public void test_34() { 
     assertNotNull(mActivity); 
    } 

    public void test_35() { 
     assertNotNull(mActivity); 
    } 

    public void test_36() { 
     assertNotNull(mActivity); 
    } 

    public void test_37() { 
     assertNotNull(mActivity); 
    } 

    public void test_38() { 
     assertNotNull(mActivity); 
    } 

    public void test_39() { 
     assertNotNull(mActivity); 
    } 

    public void test_40() { 
     assertNotNull(mActivity); 
    } 
} 

테스트 활동 활동 확장 : 여기

package my.app; 

import android.app.Activity; 

import android.os.Bundle; 

public class TestActivityAndroid extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 
} 

네이티브 여유 공간이는 30kB 이하로하고,보다 떨어진다 메모리 사용량이 여기에

내 leakTest 테스트 케이스입니다 앱이 삭제되었습니다.

 Applications Memory Usage (kB): Uptime: 3804373 Realtime: 3804373 

** MEMINFO in pid 7315 [my.app] ** 
        native dalvik other total 
      size:  4048  3271  N/A  7319 
     allocated:  3942  2306  N/A  6248 
      free:  105  965  N/A  1070 
      (Pss):  844  1590  1806  4240 
    (shared dirty):  1404  4120  2288  7812 
    (priv dirty):  736  672  992  2400 Objects 
      Views:  0  ViewRoots:  0 
    AppContexts:  0  Activities:  0 
      Assets:  2 AssetManagers:  2  
    Local Binders:  11 Proxy Binders:  10 
Death Recipients:  0  
OpenSSL Sockets:   0  
SQL 
      heap:  0  memoryUsed:  0 
pageCacheOverflo:  0 largestMemAlloc:  0 
    Asset Allocations 
    zip:/data/app/my.app-1.apk:/resources.arsc: 1K 

tearDown() 내부에서 2 초 수면을하는 사람이 더 좋은 해결책이 있습니까? 나는 tearDown() 안의 수면을 좋아하지 않는다. 테스트 스위트 내에 약 100 개의 테스트가 있으므로 2 초가 크게 지연됩니다.

누군가가 나를 도울 수 있기를 바랍니다. 제 질문이 명확하지 않으면 알려주세요.

미리 감사드립니다.

답변

2

왜 각 단위 테스트 후에 gc를 수행해야합니까?

테스트를 위해 깨끗한 환경을 원한다면 2 초 후에 실행하십시오. tearDown은 적어도 2 기가와 일부 마무리 작업을합니다. 다음 시험을위한 깨끗한 환경을 유지합니다. 안드로이드 소스 코드를 읽었을 때 테스트가 끝날 때 tearDown을 호출해야한다는 비판적인 의견이 몇 가지 있습니다.

테스트에 깨끗한 환경이 필요하지 않은 경우 테스트를 결합하십시오. 즉, 200 초 동안 진행되는 프로세스는 테스트에서 제공하는 보호 비용을 지불하는 데 약간의 대가를 치르게됩니다.

현재의 큰 프로젝트에 대한 우리의 자동화 된 테스트는 약 5 분이 걸립니다. 초기 체크인시 테스트를 실행하고 실패 할 경우 제출을 반송하도록 시스템을 자동화했기 때문에 결코 알 수 없습니다.

몇 번이나 실패했지만, 변경된 코드가 앱의 다른 섹션을 엉망으로 만들었습니다. 우리는 자동화 된 테스트를 통해 최소한 수주 동안 앱을 유지 보수하고 디버깅하는 데 많은 시간을 절약했습니다.

+0

안녕하세요. 회신 해 주셔서 감사합니다. 현재 시험에서 모든 시험에 대해 깨끗한 신선한 활동을 원합니다. 따라서 이전 테스트는 다음 테스트에 영향을 미치지 않습니다. 그러나 2 초의 지연으로 인해 'OutOfResourcesException 작성 표면'오류가 수정되는 것이 이상하다는 것을 알게되었습니다. Android의 버그 또는 표면 리소스를 충분히 빠르게 출시하지 않는 버그입니다. 그러나 지금은 퀵 빌드 설정에서 매일 실행되는 것처럼 2 초 지연 만 허용 할 것입니다. – kuipers

관련 문제