Memory leak for Android Google Maps API v2

2019-02-20 12:53发布

问题:

I'm struggling with a memory leak issue at Google Maps Android API v2. The heap usage increases by about 85KB every time my view becomes visible again after:

  • Phone screen turns off (eg after pressing the power button).
  • The user exits the app pressing the Home button.

The app eventually crashes with an OutOfMemory exception. The leak does NOT occur on screen rotate, or when exiting by "back" button. Any ideas about a workaround or the reason behind this problem?

My code:

public class LeakActivity extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_leak);
    }
}

and the XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<fragment
    android:id="@+id/map_1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.google.android.gms.maps.SupportMapFragment" />

</RelativeLayout>

回答1:

This might be related to this open issue in the Maps API:

Issue 4766 - Bug: Android Maps API v2 leaks huge amounts of memory

Use DDMS' "Dump HPROF" tool to dump a hprof file, convert it with hprof-conv and use MAT to examine the leak. If it's in Google Maps API, please post an apk (or better simple test code) to the open issue and include the hprof file.

If it is the same bug I am experiencing, it might only happen on Android 2.x, please check that too.



回答2:

I tried to use System.gc() and map.clear() before the map is initialized.

  @Override
public void onActivityCreated (Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);

    if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) == ConnectionResult.SUCCESS) {
        System.gc();
getMap().clear();
setupmap();


    }
}
 @Override
public void onLowMemory() {
  super.onLowMemory();
System.gc();
}