0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Robolectricで複数のAndroidSDKをテストした際のOutOfMemoryErrorとその対策

Posted at

事象

Robolectricは、Config アノテーションを用いて複数のAndroidSDKバージョンに対してテスト関数を連続で実行してくれる機能があります。

    @Test
    @Config(minSdk = 22, maxSdk = 34)
    fun getSdkTest() {
        
    }

この機能を用いて、SDK22〜34までをテストした際に OutOfMemoryError が発生しました。

スクリーンショット 2024-12-01 14.47.23.png

テスト対象のSDKの数を減らすと正常に完了するため、すべてのSDKバージョンのテスト完了ごとのメモリ解放ではなく、全てのテストが実行されるまで保持しているようです。

環境

  • Gradle 8.9
  • Gradle JDK 21.0.3
  • JUnit 4.13.2
  • robolectric 4.14.1

結論

対象モジュールの build.gradle.kts に、以下のように最大ヒープサイズを指定したところ解消しました。

tasks.withType<Test> {
    maxHeapSize = "1024m"
}

groovyの場合は、試していませんがおそらくこの記述となります。

test {
    maxHeapSize = "1024m"
}

デフォルトのテスト時のメモリ上限はおそらく512m程度で設定されているようです。

試してダメだったこと

gradle.properties のjvm引数での最大ヒープサイズの引き上げ

org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8

ヒープサイズといえばここの指定と思い引き上げましたが、Unitテストではこちらの指定は使われていないようで、効果無しです。

テストの分割

    @Test
    @Config(minSdk = 22, maxSdk = 29)
    fun getSdkTest1() {
        
    }

    @Test
    @Config(minSdk = 30, maxSdk = 34)
    fun getSdkTest2() {
        
    }

テスト関数を分けても、テストクラス自体を分けても、メモリを解放する挙動にはならず、一括テストでは効果はありませんでした。分割したテストを個別に実行するのであれば正常になります。

テスト完了毎にGCを呼ぶ

    @After
    fun tearDown() {
        System.gc()
    }

SDKバージョンごとにメモリ展開されたオブジェクトはGC対象ではないのでしょう。効果がありませんでした。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?