【发布时间】:2019-12-28 15:09:12
【问题描述】:
我正在将项目从 gradle 版本 3.3 转换为 4.10.1。该项目主要是使用自定义构建步骤构建的 C++ 代码,而不是 CMake (externalNativeBuild) 或 Android.mk(ndkBuild)。它产生以下库:
armeabi-v7a unstripped: 883.2MB
arm64-v8a unstripped: 864.6MB
armeabi-v7a stripped: 15.6MB
arm64-v8a stripped: 23.9MB
构建过程在 crashlyticsGenerateSymbolsGoogleDistribution 步骤失败,并出现错误 OutOfMemoryError: GC Overhead Limit Exceeded。
是否有为 crashlytics 插件步骤提供更多内存的方法或参数?
顶级 gradle.properties 文件包含以下 jvm 参数:
org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=512m - 尽管我已经尝试过和 org.gradle.jvmargs=-Xmx12g:MaxPermSize=2g 一样多的尝试。对这些值的更改似乎不会影响 crashlyticsGenerateSymbols 步骤。
如果我运行 assembleGoogleDistribution 构建,跳过 crashlytics 步骤,构建完成没有问题。
构建堆栈跟踪:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':application:crashlyticsGenerateSymbolsGoogleDistribution'.
> GC overhead limit exceeded
* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':application:crashlyticsGenerateSymbolsGoogleDistribution'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:110)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:59)
at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:59)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:101)
at org.gradle.api.internal.tasks.execution.FinalizeInputFilePropertiesTaskExecuter.execute(FinalizeInputFilePropertiesTaskExecuter.java:44)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:91)
at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:59)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.run(EventFiringTaskExecuter.java:51)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:46)
at org.gradle.execution.taskgraph.LocalTaskInfoExecutor.execute(LocalTaskInfoExecutor.java:42)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:277)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareWorkItemExecutor.execute(DefaultTaskExecutionGraph.java:262)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:135)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:130)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.execute(DefaultTaskPlanExecutor.java:200)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.executeWithWork(DefaultTaskPlanExecutor.java:191)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$ExecutorWorker.run(DefaultTaskPlanExecutor.java:130)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.interleaveRanges(DwarfDataParser.java:321)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processChildDebugInfoEntries(DwarfDataParser.java:275)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.processCompilationUnit(DwarfDataParser.java:194)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.readCompilationUnit(DwarfDataParser.java:173)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.readCompilationUnit(DwarfDataParser.java:139)
at com.crashlytics.tools.utils.dwarf.DwarfDataParser.parse(DwarfDataParser.java:62)
at com.crashlytics.tools.utils.elf.ElfDataParser.parseElf(ElfDataParser.java:131)
at com.crashlytics.tools.utils.elf.ElfDataParser.parse(ElfDataParser.java:101)
at com.crashlytics.tools.utils.elf.ElfDataParser.parse(ElfDataParser.java:39)
at com.crashlytics.tools.android.project.codemapping.csym.ElfCSymFactory.createCSymFromFile(ElfCSymFactory.java:99)
at com.crashlytics.tools.android.project.codemapping.csym.NdkCSymGenerator.generateCodeMappings(NdkCSymGenerator.java:70)
at com.crashlytics.tools.android.project.CSymManager.generate(CSymManager.java:96)
at com.crashlytics.tools.android.DeveloperTools.processProperties(DeveloperTools.java:692)
at com.crashlytics.tools.android.DeveloperTools.processArgsInternal(DeveloperTools.java:348)
at com.crashlytics.tools.android.DeveloperTools.gradleMain(DeveloperTools.java:292)
Gradle 和 Java 信息:
./gradlew --version
------------------------------------------------------------
Gradle 4.10.1
------------------------------------------------------------
Build time: 2018-09-12 11:33:27 UTC
Revision: 76c9179ea9bddc32810f9125ad97c3315c544919
Kotlin DSL: 1.0-rc-6
Kotlin: 1.2.61
Groovy: 2.4.15
Ant: Apache Ant(TM) version 1.9.11 compiled on March 23 2018
JVM: 1.8.0_121 (Oracle Corporation 25.121-b13)
OS: Mac OS X 10.13.6 x86_64
顶级 build.gradle
...
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.google.gms:google-services:4.1.0'
classpath 'io.fabric.tools:gradle:1.31.0'
}
}
...
应用程序构建.gradle
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
...
crashlytics {
enableNdk true
androidNdkOut './../../../build/crashlytics'
androidNdkLibsOut './../../../build/crashlytics/lib'
}
...
dependencies {
// Crashlytics Kit
implementation('com.crashlytics.sdk.android:crashlytics:2.10.1@aar') {
transitive = true
}
// NDK Kit
implementation('com.crashlytics.sdk.android:crashlytics-ndk:2.1.0@aar') {
transitive = true
}
}
...
(我已确认 androidNdkOut 路径包含 armeabi-v7a 和 arm64-v8a 文件夹,其中包含我们未剥离的 libnative.so 文件,而 androidNdkLibsOut 包含与我们剥离的 libnative.so 文件相同的文件夹)
我如何确保 crashlytics 插件为其 crashlyticsGenerateSymbols 步骤获得足够的内存,从而不超过垃圾收集器的开销?
【问题讨论】:
-
尝试一些旧版本的 Fabric Gradle 插件是否可以摆脱 OOM?低至 1.28.0 可能值得尝试。 docs.fabric.io/android/changelog.html#fabric-gradle-plugin
-
我尝试了包括 1.28.0 在内的所有版本,但均未成功。该项目是从 1.24.2 升级的(它工作的地方,但现在那个版本太旧了)
-
谢谢,所以无论您在生成符号时使用的插件版本如何,看起来都会发生 OOM。您能否在未剥离的二进制文件上运行以下命令并查看输出有多大?
readelf --debug-dump=info <path_to_.so> -> ~/sample/directory/dump.txt文件大小大约是我们首先读取以生成符号的原始调试信息的大小。 -
你能解决这个问题吗,因为我也遇到了同样的错误?
-
我没有,问题是我们的原生符号最终每个架构约为 6.5GB,而 Crashlytics gradle 插件根本无法处理这个问题。该插件可能应该根据需要将符号输入/输出,而不是一次将它们加载到内存结构中。我不确定这有多容易,要修复多少工作。不幸的是,这在插件开发人员手中。