Issue
I've been facing this issue (OutOfMemory) while running my espresso test suite on Kitkat and Lollipop devices. The suite runs perfectly fine on Marshmallow device. Below are more details and I would really appreciate if I could get any help in identifying the root cause of this issue. Below are more details :
- OutofMemory occurs only when I run entire suite at once (175 tests) and the issue doesn't occur if I run each test set individually.
- I tried to use System.gc() that is called after running every scenario, but still observed the OutOfmemory exception.
- The exception occurs on different test script everytime I run and is not consistent on particular feature / test script.
- The bitmaps used across the app are already compressed,so not sure if it has to do with the size of the images.
Below is the log of the recent run :
java.lang.Thread.run(Thread.java:818) 01-26 14:42:39.770 3476-4264/? E/Watchdog: !@Sync 579 [01-26 14:42:39.778] 01-26 14:42:42.470 3476-3476/? E/MotionRecognitionService: support TA ~ 01-26 14:42:45.180 4265-4317/? E/ContactsProvider_EventLog: Flush buffer to file cnt : 3 size : 0Kb duration : 39ms lastUpdatedAfter : 180367ms 01-26 14:42:52.510 3476-3476/? E/MotionRecognitionService: support TA ~ 01-26 14:42:55.320 446-454/? E/System: Uncaught exception thrown by finalizer 01-26 14:42:56.900 446-454/? E/System: java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available 01-26 14:42:56.910 446-1088/? E/CrashReporting: ParseCrashReporting caught a OutOfMemoryError exception for com.capitalone.mobilebanking.dev.debug. Building report. 01-26 14:42:56.910 446-18726/? E/CrashReporting: ParseCrashReporting caught a OutOfMemoryError exception for com.capitalone.mobilebanking.dev.debug. Building report. 01-26 14:42:56.910 446-446/? E/MonitoringInstrumentation: Exception encountered by: Thread[main,5,main]. Dumping thread state to outputs and pining for the fjords. java.lang.OutOfMemoryError: Failed to allocate a 40 byte allocation with 3960 free bytes and 3KB until OOM at android.view.View.buildDrawingCacheImpl(View.java:16723) at android.view.View.buildDrawingCache(View.java:16625) at android.view.View.draw(View.java:17231) at android.view.ViewGroup.drawChild(ViewGroup.java:3921) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3711) at android.view.View.buildDrawingCacheImpl(View.java:16759) at android.view.View.buildDrawingCache(View.java:16625) at android.view.View.updateDisplayListIfDirty(View.java:16445) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3905) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3885) at android.view.View.updateDisplayListIfDirty(View.java:16424) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:325) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:331) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:366) at android.view.ViewRootImpl.draw(ViewRootImpl.java:3134) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2933) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2522) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1437) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7397) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:920) at android.view.Choreographer.doCallbacks(Choreographer.java:695) at android.view.Choreographer.doFrame(Choreographer.java:631) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:906) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:158) at android.app.ActivityThread.main(ActivityThread.java:7224) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 01-26 14:42:56.910 446-18726/? E/AndroidRuntime: FATAL EXCEPTION: IntentService[AlertSubscriptionService] Process: com.capitalone.mobilebanking.dev.debug, PID: 446 java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available 01-26 14:42:56.910 446-1088/? E/CrashReporting: Handling exception for crash java.lang.OutOfMemoryError: Failed to allocate a 4092 byte allocation with 3928 free bytes and 3KB until OOM at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95) at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:146) at java.lang.StringBuffer.append(StringBuffer.java:219) at java.util.regex.Matcher.appendTail(Matcher.java:285) at java.util.regex.Matcher.replaceAll(Matcher.java:321) at gherkin.formatter.PrettyFormatter.indent(PrettyFormatter.java:469) at gherkin.formatter.PrettyFormatter.printError(PrettyFormatter.java:385) at gherkin.formatter.PrettyFormatter.printSteps(PrettyFormatter.java:133) at gherkin.formatter.PrettyFormatter.replay(PrettyFormatter.java:121) at gherkin.formatter.PrettyFormatter.eof(PrettyFormatter.java:421) at java.lang.reflect.Method.invoke(Native Method) at cucumber.runtime.Utils$1.call(Utils.java:34) at cucumber.runtime.Timeout.timeout(Timeout.java:13) at cucumber.runtime.Utils.invoke(Utils.java:30) at cucumber.runtime.RuntimeOptions$1.invoke(RuntimeOptions.java:243) at java.lang.reflect.Proxy.invoke(Proxy.java:393) at $Proxy11.eof(Unknown Source) at cucumber.runtime.model.CucumberFeature.run(CucumberFeature.java:165) at cucumber.runtime.android.CucumberExecutor.execute(CucumberExecutor.java:113) at cucumber.api.android.CucumberInstrumentationCore.start(CucumberInstrumentationCore.java:88) at com.capitalone.mobilebanking.espressoTests.Instrumentation.onStart(Instrumentation.java:133) at android.app.Instrumentation
Solution
I had the same issue when I started running more than 300 Espresso tests at once. Apparently, the memory is not cleared after each test which caused the OOM Error (OutOfMemoryError).
To fix the issue, I started using the Android Test Orchestrator which offers the following benefits for your testing environment:
- Minimal shared state. Each test runs in its own Instrumentation instance. Therefore, if your tests share app state, most of that shared state is removed from your device's CPU or memory after each test.
- To remove all shared state from your device's CPU and memory after each test, use the clearPackageData flag.
- Crashes are isolated. Even if one test crashes, it takes down only its own instance of Instrumentation, so the other tests in your suite still run.
I added the Android Test Orchestrator in my project build gradle file to fix the issue:
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'
}
Answered By - ZakariaBK
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.