Out of memory error during some patrol builds on Codemagic device
Steps to reproduce
- Set up a Codemagic workflow configured to run on a macOS environment (specifically, a Mac Mini M2).
- In the workflow, use the following build commands:
dart pub global activate patrol_cli
flutter build apk --config-only -t lib/$RUN_FILE --flavor $FLAVOR
patrol build android -t integration_test --verbose
- Trigger the workflow to build and run patrol tests. Ensure all necessary environment variables ($RUN_FILE, $FLAVOR, etc.) are properly configured.
- Observe the results of the build, noting any inconsistencies in the success or failure of the patrol test build step.
Actual results
Expected Outcome: The workflow completes successfully, with the patrol tests built and executed without errors.
Intermittent Issue: Occasionally, the patrol test build step fails with an "Out of memory" error.
Current Configuration: The org.gradle.jvmargs setting in gradle.properties is set to -Xmx8g.
Observation: Despite the 8 GB memory allocation, the build inconsistently fails due to memory constraints—sometimes succeeding and sometimes failing without any changes to the code or configuration.
Is there a way to correctly test whether gradle has correctly alocated 8 GB in memore?
Logs
Logs of FAILED build
: > Task :permission_handler_android:copyDebugJniLibsProjectOnly
: > Task :share_plus:mergeDebugJniLibFolders
: > Task :share_plus:mergeDebugNativeLibs NO-SOURCE
: > Task :share_plus:copyDebugJniLibsProjectOnly
: > Task :shared_preferences_android:mergeDebugJniLibFolders
: > Task :shared_preferences_android:mergeDebugNativeLibs NO-SOURCE
: > Task :shared_preferences_android:copyDebugJniLibsProjectOnly
: > Task :sqflite:mergeDebugJniLibFolders
: > Task :sqflite:mergeDebugNativeLibs NO-SOURCE
: > Task :sqflite:copyDebugJniLibsProjectOnly
: > Task :sqlcipher_flutter_libs:mergeDebugJniLibFolders
: > Task :sqlcipher_flutter_libs:mergeDebugNativeLibs NO-SOURCE
: > Task :sqlcipher_flutter_libs:copyDebugJniLibsProjectOnly
: > Task :url_launcher_android:mergeDebugJniLibFolders
: > Task :url_launcher_android:mergeDebugNativeLibs NO-SOURCE
: > Task :url_launcher_android:copyDebugJniLibsProjectOnly
: > Task :video_player_android:mergeDebugJniLibFolders
: > Task :video_player_android:mergeDebugNativeLibs NO-SOURCE
: > Task :video_player_android:copyDebugJniLibsProjectOnly
: > Task :wakelock_plus:mergeDebugJniLibFolders
: > Task :wakelock_plus:mergeDebugNativeLibs NO-SOURCE
: > Task :wakelock_plus:copyDebugJniLibsProjectOnly
: > Task :webview_flutter_android:mergeDebugJniLibFolders
: > Task :webview_flutter_android:mergeDebugNativeLibs NO-SOURCE
: > Task :webview_flutter_android:copyDebugJniLibsProjectOnly
: > Task :app:validateSigningDevDebug
: > Task :app:writeDevDebugAppMetadata
: > Task :app:writeDevDebugSigningConfigVersions
: > Task :app:mergeDevDebugNativeLibs
: > Task :app:stripDevDebugDebugSymbols
: > Task :app:packageDevDebug FAILED
: ASM Instrumentation process wasn't able to resolve some classes, this means that
: the instrumented classes might contain corrupt stack frames. Make sure the
: dependencies that contain these classes are on the runtime or the provided
: classpath. Otherwise, the jvm might fail to load the corrupt classes at runtime
: when running in a jvm environment like unit tests.
:
: Classes that weren't resolved:
: > androidx.window.extensions.embedding.ActivityEmbeddingComponent
: > androidx.window.extensions.layout.WindowLayoutComponent
: > androidx.window.sidecar.SidecarDeviceState
: > androidx.window.sidecar.SidecarInterface
: > com.google.common.util.concurrent.ListenableFuture
: > java.net.http.HttpTimeoutException
: > javax.naming.NamingException
: > javax.naming.directory.Attributes
: > sun.misc.Unsafe
: > androidx.compose.animation.tooling.ComposeAnimatedProperty
:
:
: Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
:
: You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
:
: For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
: 714 actionable tasks: 713 executed, 1 up-to-date
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:packageDevDebug'.
> A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
> java.lang.OutOfMemoryError (no error message)
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 6m 12s
✗ Failed to build apk with entrypoint test_bundle.dart (Gradle build failed with code 1) (373.5s)
Exception: Gradle build failed with code 1
#0 AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:79:9)
<asynchronous suspension>
#1 DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2 AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:49:5)
<asynchronous suspension>
#3 BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4 CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5 PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:366:18)
<asynchronous suspension>
#6 PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:310:18)
<asynchronous suspension>
#7 patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:71:20)
<asynchronous suspension>
#8 main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.2.1/bin/main.dart:6:20)
<asynchronous suspension>
See the logs above to learn what happened. Also consider running with --verbose. If the logs still aren't useful, then it's a bug - please report it.
Exception: Gradle build failed with code 1
#0 AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:79:9)
<asynchronous suspension>
#1 DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2 AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:49:5)
<asynchronous suspension>
#3 BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4 CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5 PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:366:18)
<asynchronous suspension>
#6 PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:310:18)
<asynchronous suspension>
#7 patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:71:20)
<asynchronous suspension>
#8 main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.2.1/bin/main.dart:6:20)
<asynchronous suspension>
Build failed :|
Step 8 script `Build Patrol` exited with status code 1
Logs of SUCCESSFUL build
: > Task :patrol:mergeDebugJniLibFolders UP-TO-DATE
: > Task :patrol:mergeDebugNativeLibs NO-SOURCE
: > Task :patrol:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :permission_handler_android:mergeDebugJniLibFolders UP-TO-DATE
: > Task :permission_handler_android:mergeDebugNativeLibs NO-SOURCE
: > Task :permission_handler_android:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :share_plus:mergeDebugJniLibFolders UP-TO-DATE
: > Task :share_plus:mergeDebugNativeLibs NO-SOURCE
: > Task :share_plus:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :shared_preferences_android:mergeDebugJniLibFolders UP-TO-DATE
: > Task :shared_preferences_android:mergeDebugNativeLibs NO-SOURCE
: > Task :shared_preferences_android:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :sqflite:mergeDebugJniLibFolders UP-TO-DATE
: > Task :sqflite:mergeDebugNativeLibs NO-SOURCE
: > Task :sqflite:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :sqlcipher_flutter_libs:mergeDebugJniLibFolders UP-TO-DATE
: > Task :sqlcipher_flutter_libs:mergeDebugNativeLibs NO-SOURCE
: > Task :sqlcipher_flutter_libs:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :url_launcher_android:mergeDebugJniLibFolders UP-TO-DATE
: > Task :url_launcher_android:mergeDebugNativeLibs NO-SOURCE
: > Task :url_launcher_android:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :video_player_android:mergeDebugJniLibFolders UP-TO-DATE
: > Task :video_player_android:mergeDebugNativeLibs NO-SOURCE
: > Task :video_player_android:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :wakelock_plus:mergeDebugJniLibFolders UP-TO-DATE
: > Task :wakelock_plus:mergeDebugNativeLibs NO-SOURCE
: > Task :wakelock_plus:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :webview_flutter_android:mergeDebugJniLibFolders UP-TO-DATE
: > Task :webview_flutter_android:mergeDebugNativeLibs NO-SOURCE
: > Task :webview_flutter_android:copyDebugJniLibsProjectOnly UP-TO-DATE
: > Task :app:mergeDevDebugAndroidTestNativeLibs NO-SOURCE
: > Task :app:checkDevDebugAndroidTestDuplicateClasses
: > Task :app:validateSigningDevDebugAndroidTest
: > Task :app:mergeExtDexDevDebugAndroidTest
: > Task :app:mergeLibDexDevDebugAndroidTest
: > Task :app:writeDevDebugAndroidTestSigningConfigVersions
: > Task :app:mergeProjectDexDevDebugAndroidTest
: > Task :app:packageDevDebugAndroidTest
: > Task :app:createDevDebugAndroidTestApkListingFileRedirect
: > Task :app:assembleDevDebugAndroidTest
:
: Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
:
: You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
:
: For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
:
: BUILD SUCCESSFUL in 8s
: 715 actionable tasks: 47 executed, 668 up-to-date
✓ Completed building apk with entrypoint test_bundle.dart (315.8s)
Patrol version
patrol: ^3.11.0
Patrol Doctor output
Patrol Doctor output
Patrol CLI version: 3.2.1
Flutter command: flutter
Flutter 3.24.1 • channel stable
Android:
• Program adb found in /usr/local/share/android-sdk/platform-tools/adb
• Env var $ANDROID_HOME set to /usr/local/share/android-sdk
iOS / macOS:
• Program xcodebuild found in /usr/bin/xcodebuild
• Program ideviceinstaller not found (install with `brew install ideviceinstaller`)
Flutter Doctor output
Flutter Doctor output
<!-- Replace this line with your logs. Do not remove the backticks! -->
Hi @martin1080p ! Some additional questions:
- Have this error occurred locally as well?
- Can you provide a project with Codemagic CI configured so we can debug this?
I checked my project and org.gradle.jvmargs is set to Xmx4608m, so even less and I never encountered this error. Do you build the tests multiple times on the same workflow, so the machine is not clean? Or this happens on a clean machine?
Maybe this much memory is indeed needed, but it is unlikely imo. Did you try to increase this parameter?
This error hasn't occurred when tested locally on Win, Linux and Mac.
This parameter was already increased from -Xms2048M, where the same error occurred as well. But sometimes like with this setting, it has been built successfully.
Unfortunately I am unable to share the whole project since it's commercial. However I might be able to share some pieces of code on demand.
I think we should search for solution around the workflow or codemagic machines. Could you share what your workflow looks like? Can be just steps names, maybe there is something that consumes most of the memory before building
We also found this, maybe you'll find it helpful: https://docs.codemagic.io/troubleshooting/common-android-issues/#java-heap-space-out-of-memory-error
@jBorkowska
android-integration-tests:
name: Android Integration tests
environment:
<<: *android-apk-environment
vars: *dev-variables
scripts:
- *tools-setup
- *android-local-props-setup
- *project-setup
# - *analyze
# - *dcm
# - *tests
- name: Patrol and GCloud setup
script: |
echo "Install patrol_cli"
dart pub global activate patrol_cli
patrol doctor
echo "Setting up GCloud"
echo $FIREBASE_INTEGRATION_KEY > ./gcloud_key_file.json
gcloud auth activate-service-account --key-file=gcloud_key_file.json
gcloud projects list
gcloud --quiet config set project $FIREBASE_PROJECT_ID
# TODO: TEMP solution
gcloud components update
#- *build-apk-android
- name: Build Patrol
working_directory: apps/bakalari
script: |
# Generate gradlew first
flutter build apk --config-only -t lib/$RUN_FILE --flavor $FLAVOR
patrol build android -t integration_test --verbose
- name: Wakeup server
script: curl --head --connect-timeout 60 --max-time 90 https://11.ext.bakalari.cz/
- name: Run test
working_directory: apps/bakalari
script: |
echo "Starting tests"
./scripts/firebase-test-lab-android.sh -l "$PROJECT_BUILD_NUMBER" -t 5m -p android-preset-small
- In
tools-setupit just setups cloudsmith and melos android-local-props-setupis setting environment variablesproject-setuprunsmelos
@jBorkowska Hi can we investigate it further? For us it is currently blocker and we would like to run tests automatically with codemagic
You can try adding this line to android/gradle.properties:
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
A heap dump can be helpful in pinpointing the cause.
@bartekpacia Thanks for help, unfortunately the build still fails due to memory overflow.
Log
: > Task :webview_flutter_android:copyDebugJniLibsProjectOnly
: > Task :app:validateSigningDevDebug
: > Task :app:writeDevDebugAppMetadata
: > Task :app:writeDevDebugSigningConfigVersions
: > Task :app:mergeDevDebugNativeLibs
: > Task :app:stripDevDebugDebugSymbols
: > Task :app:packageDevDebug FAILED
: ASM Instrumentation process wasn't able to resolve some classes, this means that
: the instrumented classes might contain corrupt stack frames. Make sure the
: dependencies that contain these classes are on the runtime or the provided
: classpath. Otherwise, the jvm might fail to load the corrupt classes at runtime
: when running in a jvm environment like unit tests.
:
: Classes that weren't resolved:
: > com.google.common.util.concurrent.ListenableFuture
: > sun.misc.Unsafe
: > androidx.window.extensions.embedding.ActivityEmbeddingComponent
: > androidx.window.extensions.layout.WindowLayoutComponent
: > androidx.window.sidecar.SidecarDeviceState
: > androidx.window.sidecar.SidecarInterface
: > androidx.compose.animation.tooling.ComposeAnimatedProperty
: > java.net.http.HttpTimeoutException
: > javax.naming.NamingException
: > javax.naming.directory.Attributes
:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:packageDevDebug'.
> A failure occurred while executing com.android.build.gradle.tasks.PackageAndroidArtifact$IncrementalSplitterRunnable
> java.lang.OutOfMemoryError (no error message)
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 3m 8s
:
: Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
:
: You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
:
: For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
: 714 actionable tasks: 709 executed, 5 up-to-date
✗ Failed to build apk with entrypoint test_bundle.dart (Gradle build failed with code 1) (189.7s)
Exception: Gradle build failed with code 1
#0 AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:81:9)
<asynchronous suspension>
#1 DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2 AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:51:5)
<asynchronous suspension>
#3 BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4 CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5 PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:384:18)
<asynchronous suspension>
#6 PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:328:18)
<asynchronous suspension>
#7 patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:75:20)
<asynchronous suspension>
#8 main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.5.0/bin/main.dart:6:20)
<asynchronous suspension>
See the logs above to learn what happened. Also consider running with --verbose. If the logs still aren't useful, then it's a bug - please report it.
Exception: Gradle build failed with code 1
#0 AndroidTestBackend.build.<anonymous closure> (package:patrol_cli/src/android/android_test_backend.dart:81:9)
<asynchronous suspension>
#1 DisposeScope.run (package:dispose_scope/src/dispose_scope.dart:46:7)
<asynchronous suspension>
#2 AndroidTestBackend.build (package:patrol_cli/src/android/android_test_backend.dart:51:5)
<asynchronous suspension>
#3 BuildAndroidCommand.run (package:patrol_cli/src/commands/build_android.dart:160:7)
<asynchronous suspension>
#4 CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#5 PatrolCommandRunner.runCommand (package:patrol_cli/src/runner/patrol_command_runner.dart:384:18)
<asynchronous suspension>
#6 PatrolCommandRunner.run (package:patrol_cli/src/runner/patrol_command_runner.dart:328:18)
<asynchronous suspension>
#7 patrolCommandRunner (package:patrol_cli/src/runner/patrol_command_runner.dart:75:20)
<asynchronous suspension>
#8 main (file:///Users/builder/.pub-cache/hosted/pub.dev/patrol_cli-3.5.0/bin/main.dart:6:20)
<asynchronous suspension>
Build failed :|
Step 8 script `Build Patrol` exited with status code 1
@bartekpacia @jBorkowska Do you think we can move on somehow with this issue? We've tried everyting suggested but no luck.
For our, quite big project, it is show stopper and really blocker.
Hey @martin1080p did you try solution suggested by codemagic there: https://docs.codemagic.io/troubleshooting/common-android-issues/#java-heap-space-out-of-memory-error-or-jvm-garbage-collector-is-thrashing? Set JAVA_TOOL_OPTIONS: "-Xmx5g" in the Codemagic workflow setup
workflows:
android-workflow:
# ....
environment:
groups:
# ...
vars:
JAVA_TOOL_OPTIONS: "-Xmx5g"
There's a thread about this issue in the Codemagic discord: https://discord.com/channels/1131597315707261018/1345307837190115328
Without additional information, we can't resolve this issue. We're therefore reluctantly going to close it. Feel free to open a new issue with all the required information provided, including a [minimal, reproducible sample]. Make sure to diligently fill out the issue template. Thanks for your contribution. [minimal, reproducible sample]: https://stackoverflow.com/help/minimal-reproducible-example
This issue has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar problem, please file a new issue. Make sure to follow the template and provide all the information necessary to reproduce the issue.