Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[Compose Extension] OOM crash in GeoJsonSourceState when data contains large feature list

オープン 初心者向け
#2,727 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
76/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
android, kotlin

調査の方向性

まず extension-compose/src/main/java/com/mapbox/maps/extension/compose/style/sources/SourceState.kt の 230 行目付近にある launchCollectGeoJsonData から始め、次に PropertyTypes.kt の GeoJSONData.toString() を調べます。大きな GeoJSONData の feature リストで再現し、source の更新時に feature リスト全体の文字列を構築しようとしたり、OutOfMemoryError でクラッシュしたりしなくなったことを確認します。

索引モデルが issue の本文から書いたものです。

説明

bug :beetle:

Environment

  • Android OS version: Any (lower-end devices with smaller growth limits hit it sooner)
  • Devices affected: Any. Reproducible when the GeoJSON feature list is sufficiently large (crash observed at ~143 MB allocation attempt with a 201 MB growth limit)
  • Maps SDK Version: Confirmed present on main as of the date of this report.

Observed behavior and steps to reproduce

App crashes with OutOfMemoryError when a GeoJsonSourceState is backed by a GeoJSONData(List) containing a large number of features, due to an internal log call.

Steps:

  1. Create a GeoJsonSourceState -> sourceState.data = GeoJSONData(listOfFeatures).
  2. Observe the app crash with the following OOM.
val sourceState = remember(sourceId) {
            GeoJsonSourceState(sourceId = sourceId).apply {
                ...
            }
        }

        LaunchedEffect(features) {
            withContext(Dispatchers.Default) {
                val finalFeatures = features.map { it.toMapboxFeature() }
                sourceState.data = GeoJSONData(finalFeatures)
            }
        }

        sourceState

Stack trace:

java.lang.OutOfMemoryError: Failed to allocate a 143240712 byte allocation with 25165824 free bytes and 49MB until OOM, target footprint 174756928, growth limit 201326592
    at java.util.Arrays.copyOf(Arrays.java:3766)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:125)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:449)
    at java.lang.StringBuilder.append(StringBuilder.java:137)
    at java.lang.StringBuilder.append(StringBuilder.java:132)
    at java.util.AbstractCollection.toString(AbstractCollection.java:473)
    at com.mapbox.maps.extension.compose.style.sources.GeoJSONData.toString(PropertyTypes.kt:335)
    at java.lang.String.valueOf(String.java:3657)
    at java.lang.StringBuilder.append(StringBuilder.java:132)
    at com.mapbox.maps.extension.compose.style.sources.SourceState$launchCollectGeoJsonData$1.invokeSuspend(SourceState.kt:230)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.java:34)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
    at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:124)
    at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89)
    at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.execTask(CoroutineScheduler.kt:798)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:798)
    at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:717)

Suppressed:
    kotlinx.coroutines.internal.DiagnosticCoroutineContextException:
    [CoroutineName(SourceStateMapboxMapScope_gps_source),
    StandaloneCoroutine{Cancelling}@5888d8a,
    Dispatchers.IO]

Expected behavior

GeoJsonSourceState should handle large feature collections without crashing. Updating a source with thousands of GPS points is a standard use case. The SDK should not attempt to serialize the full feature list into a single String as a side-effect of a log call.

Notes / preliminary analysis

SourceState.kt:230 eager toString() in a log statement

// SourceState.kt ~line 228-233
private fun CoroutineScope.launchCollectGeoJsonData(mapboxMap: MapboxMap) =
   launch(Dispatchers.IO) {
       geoJSONDataChannel.consumeEach { data ->
           logD(TAG, "setGeoJsonSourceData: $data")  // <-- triggers toString() unconditionally
           ...
       }
   }

Additional links and references

SourceState.kt — launchCollectGeoJsonData
(https://github.com/mapbox/mapbox-maps-android/blob/main/extension-compos
e/src/main/java/com/mapbox/maps/extension/compose/style/sources/SourceSta
te.kt)

PropertyTypes.kt — GeoJSONData.toString()
(https://github.com/mapbox/mapbox-maps-android/blob/main/extension-compos
e/src/main/java/com/mapbox/maps/extension/compose/style/sources/PropertyT
ypes.kt)

主要言語
Kotlin
スター
578
フォーク
163
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

mapbox/mapbox-maps-android のほかの issue

mapbox/mapbox-maps-android の issue をすべて見る

似ている issue

Kotlin の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。