android - robolectric memory leak due to numeorus ReceiverDispatcher and Activity instances -


i'm writing unit tests company's project. recently, our jenkins builds started failing during unit test gradle task outofmemory exceptions (caused either gc overhead limit exceeded or java heap space). on local machine unit testing suceeds, uses 3.5 gb of memory. there on 1000 tests in project, hundreds of them create activity instance.

i've took heap dump (in moment when 1000 tests passed) , examined visualvm. both memory usage , heap size rising, suspect there's memory leak occurring somewhere.

i've run eclipse memory analyzer heap dump , #1 leak suspect numerous receiverdispatcher instances, 255k of them (using > 500 mb of memory). also, heap contains same number of intentreceiverleaked instances, more (258k) shadowbroadcastreceiver instances, , twice less (about 127k) accessibilitymanagerservice , lockpatternutils instances.

this looks strange me, because found 1 broadcastreceiver being registered dynamically in project (in mainactivity), , it's being unregistered in activity's ondestroy() method.

since there 300 activity instances in dump, suspect leaking activities main cause of leak. also, eclipse memory analyzer lists shadowcontextimpl #2 problem suspect, more instances activities (but 500 mb of memory used).

activities in tests created using robolectric.setupactivity(), , relevant lifecycle methods called on teardown()

//android annotations in use protected activitycontroller<mainactivity_> activitycontroller; protected mainactivity_ mainactivity;  @before public void setup() throws exception {     activitycontroller = robolectric.buildactivity(mainactivity_.class).setup();     mainactivity = activitycontroller.get(); }  @after public void teardown() throws exception {     try {         if (activitycontroller != null) {             activitycontroller.pause()                     .stop()                     .destroy();         }     } catch (throwable th){}      mainactivity = null;     activitycontroller = null; } 

for fragment-related tests, fragment created , attached activity in regular way (instead of using fragmenttestutil)

public static void startfragment(fragment fragment, fragmentactivity activity) {     shadowof(looper.getmainlooper()).pause();     fragmentmanager fragmentmanager = activity.getsupportfragmentmanager();     fragmenttransaction fragmenttransaction = fragmentmanager.begintransaction();     fragmenttransaction.add(fragment, null);     fragmenttransaction.commitallowingstateloss();     shadowof(looper.getmainlooper()).runtoendoftasks(); }  (...)     activity activity = robolectric.setupactivity(mainactivity_.class); myfragment fragment = myfragment_.builder().build(); startfragment(fragment, activity); (...)  

what cause of leaks (and how fix it) ? way activities , fragments initiated have leak ?


Comments