FeatureCollection.fromFeatures() should not get out of memory for 240.000 features. It's only 15 MB
Notes / preliminary analysis
I think you can use the Gson streaming API to stream the data, instead of trying to load it all at once with Gson.toJson().
Additional links and references
java.lang.OutOfMemoryError: Failed to allocate a 150994952 byte allocation with 84761584 free bytes and 80MB until OOM, target footprint 268435456, growth limit 268435456 at java.util.Arrays.copyOf(Arrays.java:3766) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:125) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:542) at java.lang.StringBuffer.append(StringBuffer.java:350) at java.io.StringWriter.write(StringWriter.java:122) at com.google.gson.stream.JsonWriter.string(JsonWriter.java:590) at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:401) at com.google.gson.stream.JsonWriter.value(JsonWriter.java:416) at com.google.gson.internal.bind.TypeAdapters$29.write(TypeAdapters.java:746) at com.google.gson.internal.bind.TypeAdapters$29.write(TypeAdapters.java:760) at com.google.gson.internal.bind.TypeAdapters$29.write(TypeAdapters.java:698) at com.google.gson.internal.bind.TypeAdapters$35$1.write(TypeAdapters.java:890) at com.mapbox.geojson.Feature$GsonTypeAdapter.write(Feature.java:568) at com.mapbox.geojson.Feature$GsonTypeAdapter.write(Feature.java:497) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61) at com.mapbox.geojson.FeatureCollection$GsonTypeAdapter.write(FeatureCollection.java:328) at com.mapbox.geojson.FeatureCollection$GsonTypeAdapter.write(FeatureCollection.java:278) at com.google.gson.Gson.toJson(Gson.java:704) at com.google.gson.Gson.toJson(Gson.java:683) at com.google.gson.Gson.toJson(Gson.java:638) at com.google.gson.Gson.toJson(Gson.java:618) at com.mapbox.geojson.FeatureCollection.toJson(FeatureCollection.java:223) at com.mapbox.maps.extension.style.utils.TypeUtilsKt.toValue(TypeUtils.kt:329) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource.toPropertyValue(GeoJsonSource.kt:331) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource.applyGeoJsonData$lambda-11$lambda-10(GeoJsonSource.kt:353) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource.$r8$lambda$_9l_l-ZA5tTLYApH7jbY6OB3HUI(Unknown Source:0) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource$$ExternalSyntheticLambda1.run(Unknown Source:4) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.os.HandlerThread.run(HandlerThread.java:67)
Environment
Observed behavior and steps to reproduce
Mapbox crashes when making featureCollection from too many features.
Steps to reproduce:
Creating of feature on our side:
Feature.fromGeometry( point ).apply { addStringProperty(ID_FEATURE_PROPERTY, id) addStringProperty(MAP_MARKER_TYPE_FEATURE_PROPERTY, toMapMarkerType().name) addNumberProperty(LONGITUDE_FEATURE_PROPERTY, point.longitude()) addNumberProperty(LATITUDE_FEATURE_PROPERTY, point.latitude()) }
Expected behavior
FeatureCollection.fromFeatures() should not get out of memory for 240.000 features. It's only 15 MB
Notes / preliminary analysis
I think you can use the Gson streaming API to stream the data, instead of trying to load it all at once with Gson.toJson().
Additional links and references
java.lang.OutOfMemoryError: Failed to allocate a 150994952 byte allocation with 84761584 free bytes and 80MB until OOM, target footprint 268435456, growth limit 268435456 at java.util.Arrays.copyOf(Arrays.java:3766) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:125) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:542) at java.lang.StringBuffer.append(StringBuffer.java:350) at java.io.StringWriter.write(StringWriter.java:122) at com.google.gson.stream.JsonWriter.string(JsonWriter.java:590) at com.google.gson.stream.JsonWriter.writeDeferredName(JsonWriter.java:401) at com.google.gson.stream.JsonWriter.value(JsonWriter.java:416) at com.google.gson.internal.bind.TypeAdapters$29.write(TypeAdapters.java:746) at com.google.gson.internal.bind.TypeAdapters$29.write(TypeAdapters.java:760) at com.google.gson.internal.bind.TypeAdapters$29.write(TypeAdapters.java:698) at com.google.gson.internal.bind.TypeAdapters$35$1.write(TypeAdapters.java:890) at com.mapbox.geojson.Feature$GsonTypeAdapter.write(Feature.java:568) at com.mapbox.geojson.Feature$GsonTypeAdapter.write(Feature.java:497) at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97) at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61) at com.mapbox.geojson.FeatureCollection$GsonTypeAdapter.write(FeatureCollection.java:328) at com.mapbox.geojson.FeatureCollection$GsonTypeAdapter.write(FeatureCollection.java:278) at com.google.gson.Gson.toJson(Gson.java:704) at com.google.gson.Gson.toJson(Gson.java:683) at com.google.gson.Gson.toJson(Gson.java:638) at com.google.gson.Gson.toJson(Gson.java:618) at com.mapbox.geojson.FeatureCollection.toJson(FeatureCollection.java:223) at com.mapbox.maps.extension.style.utils.TypeUtilsKt.toValue(TypeUtils.kt:329) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource.toPropertyValue(GeoJsonSource.kt:331) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource.applyGeoJsonData$lambda-11$lambda-10(GeoJsonSource.kt:353) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource.$r8$lambda$_9l_l-ZA5tTLYApH7jbY6OB3HUI(Unknown Source:0) at com.mapbox.maps.extension.style.sources.generated.GeoJsonSource$$ExternalSyntheticLambda1.run(Unknown Source:4) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.os.HandlerThread.run(HandlerThread.java:67)