6

テストするメソッドがたくさんあるアクティビティの単体テストを作成しようとしています。しかし、約 31 回のテストの後、ヒープのメモリが不足しているため、アプリケーションは強制終了されます。

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 が十分に高速ではないように感じます。

これが私のleakTestテストケースです:

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 未満に低下し、アプリが強制終了された場合のメモリ使用量です。

        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 秒の遅延は非常に大きくなります。

誰かが私を助けてくれることを願っています。私の質問が明確でない場合はお知らせください。

前もって感謝します。

4

1 に答える 1

2

各ユニットテストの後にgcを実行する必要があるのはなぜですか?

テストにクリーンな環境が必要なためである場合は、2秒の遅延で生きてください。tearDownは少なくとも2gcといくつかのファイナライズを行います。それはあなたの次のテストのためにきれいな環境を残します。Androidのソースコードを読んだ場合、テストの最後にtearDownを呼び出すことが非常に必要であることを示すコメントがいくつかあります。

テストにクリーンな環境が必要ない場合は、それらを組み合わせます。そうは言っても、舞台裏で実行されているプロセスの200秒は、テストが提供する保護のために支払う小さな代償です。

現在の大きなプロジェクトでの自動テストの実行には、約5分かかります。最初のチェックイン時にテストを実行し、失敗した場合は送信をバウンスするようにシステムを自動化したため、私は気づきません。

何度か失敗しましたが、変更したコードがアプリの他のセクションを台無しにしてしまったことに本当に驚いています。自動テストを使用して、アプリのメンテナンスとデバッグに少なくとも数週間、場合によっては何ヶ月も節約できました。

于 2013-03-22T06:25:33.097 に答える