在Android

时间:2017-01-29 04:42:15

标签: java android out-of-memory android-espresso

在Kitkat和Lollipop设备上运行我的espresso测试套件时,我一直面临着这个问题(OutOfMemory)。套房在Marshmallow设备上运行完美。以下是更多细节,如果我能找到任何帮助来确定此问题的根本原因,我将非常感谢。以下是更多细节:

  1. 只有当我一次运行整个套件(175次测试)时才会出现OutofMemory,如果我单独运行每个测试集,则不会出现问题。
  2. 我尝试使用在运行每个场景后调用的System.gc(),但仍然观察到OutOfmemory异常。
  3. 每次运行时,异常都会发生在不同的测试脚本上,并且在特定功能/测试脚本上不一致。
  4. 应用程序中使用的位图已经过压缩,因此不确定是否与图像大小有关。
  5. 以下是最近一次运行的日志:

    java.lang.Thread.run(Thread.java:818) 01-26 14:42:39.770 3476-4264 /? E /看门狗:!@Sync 579 [01-26 14:42:39.778] 01-26 14:42:42.470 3476-3476 /? E / MotionRecognitionService:支持TA~ 01-26 14:42:45.180 4265-4317 /? E / ContactsProvider_EventLog:刷新缓冲区到文件cnt:3大小:0Kb持续时间:39ms lastUpdatedAfter:180367ms 01-26 14:42:52.510 3476-3476 /? E / MotionRecognitionService:支持TA~ 01-26 14:42:55.320 446-454 /? E / System:终结器抛出的未捕获异常 01-26 14:42:56.900 446-454 /? E / System:java.lang.OutOfMemoryError:尝试抛出OutOfMemoryError时抛出OutOfMemoryError;没有堆栈跟踪可用 01-26 14:42:56.910 446-1088 /? E / CrashReporting:ParseCrashReporting捕获了com.capitalone.mobilebanking.dev.debug的OutOfMemoryError异常。建立报告。 01-26 14:42:56.910 446-18726 /? E / CrashReporting:ParseCrashReporting捕获了com.capitalone.mobilebanking.dev.debug的OutOfMemoryError异常。建立报告。 01-26 14:42:56.910 446-446 /? E / MonitoringInstrumentation:遇到的异常:Thread [main,5,main]。将线程状态转储到输出并为峡湾倾斜。                                                        java.lang.OutOfMemoryError:无法分配40字节分配,其中3960个空闲字节和3KB,直到OOM                                                           在android.view.View.buildDrawingCacheImpl(View.java:16723)                                                           在android.view.View.buildDrawingCache(View.java:16625)                                                           在android.view.View.draw(View.java:17231)                                                           在android.view.ViewGroup.drawChild(ViewGroup.java:3921)                                                           在android.view.ViewGroup.dispatchDraw(ViewGroup.java:3711)                                                           在android.view.View.buildDrawingCacheImpl(View.java:16759)                                                           在android.view.View.buildDrawingCache(View.java:16625)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16445)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905)                                                           在android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885)                                                           在android.view.View.updateDisplayListIfDirty(View.java:16424)                                                           在android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:325)                                                           在android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:331)                                                           在android.view.ThreadedRenderer.draw(ThreadedRenderer.java:366)                                                           在android.view.ViewRootImpl.draw(ViewRootImpl.java:3134)                                                           在android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2933)                                                           在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2522)                                                           在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1437)                                                           在android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:7397)                                                           在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:920)                                                           在android.view.Choreographer.doCallbacks(Choreographer.java:695)                                                           在android.view.Choreographer.doFrame(Choreographer.java:631)                                                           在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:906)                                                           在android.os.Handler.handleCallback(Handler.java:739)                                                           在android.os.Handler.dispatchMessage(Handler.java:95)                                                           在android.os.Looper.loop(Looper.java:158)                                                           在android.app.ActivityThread.main(ActivityThread.java:7224)                                                           at java.lang.reflect.Method.invoke(Native Method)                                                           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1230)                                                           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 01-26 14:42:56.910 446-18726 /? E / AndroidRuntime:致命例外:IntentService [AlertSubscriptionService]                                              处理:com.capitalone.mobilebanking.dev.debug,PID:446                                               java.lang.OutOfMemoryError:尝试抛出OutOfMemoryError时抛出OutOfMemoryError;没有堆栈跟踪可用 01-26 14:42:56.910 446-1088 /? E / CrashReporting:处理崩溃异常                                              java.lang.OutOfMemoryError:无法分配4092字节的分配,其中3928个空闲字节和3KB,直到OOM                                                 at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95)                                                 在java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:146)                                                 在java.lang.StringBuffer.append(StringBuffer.java:219)                                                 在java.util.regex.Matcher.appendTail(Matcher.java:285)                                                 在java.util.regex.Matcher.replaceAll(Matcher.java:321)                                                 在gherkin.formatter.PrettyFormatter.indent(PrettyFormatter.java:469)                                                 at gherkin.formatter.PrettyFormatter.printError(PrettyFormatter.java:385)                                                 在gherkin.formatter.PrettyFormatter.printSteps(PrettyFormatter.java:133)                                                 在gherkin.formatter.PrettyFormatter.replay(PrettyFormatter.java:121)                                                 在gherkin.formatter.PrettyFormatter.eof(PrettyFormatter.java:421)                                                 at java.lang.reflect.Method.invoke(Native Method)                                                 在cucumber.runtime.Utils $ 1.call(Utils.java:34)                                                 在cucumber.runtime.Timeout.timeout(Timeout.java:13)                                                 在cucumber.runtime.Utils.invoke(Utils.java:30)                                                 在cucumber.runtime.RuntimeOptions $ 1.invoke(RuntimeOptions.java:243)                                                 在java.lang.reflect.Proxy.invoke(Proxy.java:393)                                                 在$ Proxy11.eof(未知来源)                                                 在cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165)                                                 在cucumber.runtime.android.CucumberExecutor.execute(CucumberExecutor.java:113)                                                 在cucumber.api.android.CucumberInstrumentationCore.start(CucumberInstrumentationCore.java:88)                                                 在com.capitalone.mobilebanking.espressoTests.Instrumentation.onStart(Instrumentation.java:133)                                                 在android.app.Instrumentation

1 个答案:

答案 0 :(得分:2)

当我一次开始运行300多个Espresso测试时,我遇到了同样的问题。 显然,每次导致OOM错误(OutOfMemoryError)的测试后,内存都不会清除。

为解决此问题,我开始使用Android Test Orchestrator,它为您的测试环境提供了以下好处:

  • 最小共享状态。每个测试都在自己的仪器中运行 实例。因此,如果您的测试共享应用状态,则大多数 每次共享状态从设备的CPU或内存中删除后, 测试。
  • 在运行后要从设备的CPU和内存中删除所有共享状态 每次测试时,请使用clearPackageData标志。
  • 崩溃是隔离的。即使一个测试崩溃,它也只会崩溃 它自己的Instrumentation实例,因此套件中的其他测试 仍在运行。

我在项目构建gradle文件中添加了Android Test Orchestrator,以解决此问题:

android {
  defaultConfig {
   ...
   testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

   // The following argument makes the Android Test Orchestrator run its
   // "pm clear" command after each test invocation. This command ensures
   // that the app's state is completely cleared between tests.
   testInstrumentationRunnerArguments clearPackageData: 'true'
 }

  testOptions {
    execution 'ANDROIDX_TEST_ORCHESTRATOR'
  }
}

dependencies {
  androidTestImplementation 'androidx.test:runner:1.1.0'
  androidTestUtil 'androidx.test:orchestrator:1.1.0'
}