| Issue 8596: | MapView Memory Leak | |
| 36 people starred this issue and may be notified of changes. | Back to list |
Support library 23.0.1 (happens from 22...) Android 5.1.1, not sure if it hapens in others. I´m getting a memory leak (thanks to leak canary https://github.com/square/leakcanary) with MapView inside a Fragment. I call mapView.onResume, onCreate, onPause, onDestroy, onLowMemory on each fragment event. My Layout looks like: ``` <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/status_layout_main" android:layout_width="fill_parent" android:layout_height="fill_parent" android:baselineAligned="false"> <com.google.android.gms.maps.MapView android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/status_layout_assigned" /> ... ``` There´s a related issue here http://stackoverflow.com/questions/19061488/android-mapview-v2-context-issues-and-memory-leak. I uploaded the heap_dump and a memory leak description. Here´s the head_dump.htprof https://www.dropbox.com/s/t6l4mt2vdavdb1v/heap_dump_3.hprof?dl=0 From here https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=185902
Sep 14, 2015
Project Member
#1
[email protected]
Labels:
ApiType-Android2 Type-Defect
Sep 14, 2015
Thanks for the report! Are you using the My Location layer by any chance? (See https://code.google.com/p/gmaps-api-issues/issues/detail?id=8111 ) Could you please try the workaround mentioned in that issue (disabling the my location layer in onDestroy or in onPause.)
Status:
NeedsMoreInfo
Sep 16, 2015
Every time I need to do something I get the googleMap with getMapAsync and then, inside use it. That´s wrong? should I save the googleMap Instance and use it everywhere and then set as null in onDestroy? Ex: mapView.getMapAsync(googleMap -> googleMap.setMyLocationEnabled(true));
Nov 19, 2015
Hello, I get same leak. Each time I switch tabs to the Fragment tab that I have
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
device memory drops by about 50MB! I have implemented also map.setMyLocationEnabled(false) in onPause of the Fragment.
My fragment that has the map extends Fragment (can't extend the MapFragment) like this:
public class FragmentMap extends Fragment implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener,
OnMapReadyCallback {
Thanks
Nov 20, 2015
Hello, I did one more test using the the https://github.com/googlemaps/android-samples ApiDemos, where in the MapInPagerDemoActivity, in MyAdapter, I did this change: @Override public Fragment getItem(int position) { switch (position) { case 0: return new FragmentMap().newInstance(position); case 1: case 2: return new TextFragment(); // case 3: // return new TextFragment(); // case 4: // return SupportMapFragment.newInstance(); default: return null; } } where FragmentMap is as follows: public class FragmentMap extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, OnMapReadyCallback {...} There is still leakage, going in the most right tab, and coming back to the fragment map, even if map.setMyLocationEnabled(false); Using: compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.google.android.gms:play-services:8.1.0' Thanks
Nov 20, 2015
Similar leak as in #4, #5, but now with:
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.google.android.gms:play-services:8.3.0'
Dec 6, 2015
Can you share the LeakCanary trace from the lastest version of Google Play Services? We fixed the 'my location layer' Activity leak previously: https://code.google.com/p/gmaps-api-issues/issues/detail?id=8111
Dec 6, 2015
I also had same memory leak with 8.3, we are currently fixing it with the setMyLocationEnabled(false). It doesn't appear to be fixed
Dec 10, 2015
I was able to get a leak log with a KitKat phone (thanks to leakcanary https://github.com/square/leakcanary): Using #5 with the #6 modification, please find the leak snapshot: 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: In com.example.mapdemo:1.0:1. 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * com.example.mapdemo.MapInPagerDemoActivity has leaked: 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * GC ROOT com.google.android.gms.location.internal.zzk$zzc.zzaLV 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * references com.google.android.gms.location.internal.zzk$zzb.zzaLX 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * references com.example.mapdemo.FragmentMap.mapView 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * references com.google.android.gms.maps.MapView.mContext 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * leaks com.example.mapdemo.MapInPagerDemoActivity instance 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * Reference Key: 9a962b42-ea48-48ae-a323-603de5f144d8 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * Device: HUAWEI Huawei HUAWEI Y550-L01 Y550-L01 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * Android Version: 4.4.4 API: 19 LeakCanary: 1.3.1 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * Durations: watch=5379ms, gc=179ms, heap dump=877ms, analysis=21731ms 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * Details: 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * Instance of com.google.android.gms.location.internal.zzk$zzc 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | zzaLV = com.google.android.gms.location.internal.zzk$zzb [id=0x42271230] 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mDescriptor = java.lang.String [id=0x42274ee0] 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mOwner = com.google.android.gms.location.internal.zzk$zzc [id=0x422758f8] 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mObject = 1627806640 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: * Instance of com.google.android.gms.location.internal.zzk$zzb 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | zzaLX = com.example.mapdemo.FragmentMap [id=0x42414398] 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mQueue = android.os.MessageQueue [id=0x4224cd90] 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mCallback = null 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mLooper = android.os.Looper [id=0x4224cd78] 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mMessenger = null 12-10 15:36:37.457 937-3993/com.example.mapdemo D/LeakCanary: | mAsynchronous = false
Dec 10, 2015
And some more (different?): 1. 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: In com.example.mapdemo:1.0:1. 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * com.example.mapdemo.MapInPagerDemoActivity has leaked: 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * GC ROOT com.google.android.gms.location.internal.zzk$zzc.zzaLV 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * references com.google.android.gms.location.internal.zzk$zzb.zzaLX 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * references com.example.mapdemo.FragmentMap.mGoogleApiClient 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * references com.google.android.gms.internal.zzmg.mContext 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * leaks com.example.mapdemo.MapInPagerDemoActivity instance 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * Reference Key: bd5e9fc1-49a6-496b-8855-a5db4e8895e2 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * Device: HUAWEI Huawei HUAWEI Y550-L01 Y550-L01 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * Android Version: 4.4.4 API: 19 LeakCanary: 1.3.1 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * Durations: watch=5343ms, gc=213ms, heap dump=1601ms, analysis=23065ms 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * Details: 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * Instance of com.google.android.gms.location.internal.zzk$zzc 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | zzaLV = com.google.android.gms.location.internal.zzk$zzb [id=0x42822e18] 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mDescriptor = java.lang.String [id=0x42274ee0] 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mOwner = com.google.android.gms.location.internal.zzk$zzc [id=0x42822dd0] 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mObject = 1623503240 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: * Instance of com.google.android.gms.location.internal.zzk$zzb 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | zzaLX = com.example.mapdemo.FragmentMap [id=0x427a5ae8] 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mQueue = android.os.MessageQueue [id=0x4224cd90] 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mCallback = null 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mLooper = android.os.Looper [id=0x4224cd78] 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mMessenger = null 12-10 15:59:28.177 937-3176/com.example.mapdemo D/LeakCanary: | mAsynchronous = false
Dec 10, 2015
Are you seeing the same issue with the original code in MapInPagerDemoActivity? (Ie. using MapFragment directly?) It sounds like it might be an issue in your custom Fragment. Are you forwarding all calls to super in the lifecycle callbacks? Are you holding onto any maps-related objects in your fragment past its lifecycle?
Dec 15, 2015
Here is another leak trace (using the example of posts #5 and #6), hope it's helpful: 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: In com.example.mapdemo:1.0:1. 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * com.example.mapdemo.MapInPagerDemoActivity has leaked: 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * GC ROOT static com.google.maps.api.android.lib6.gmm6.h.q.j 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.q.f 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.g.f 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.t.g 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references java.util.concurrent.CopyOnWriteArrayList.elements 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references array java.lang.Object[].[0] 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.m.cy.g 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.m.bf.k 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.c.y.mParent 12-15 20:35:39.103 17227-20885/com.example.mapdemo D/LeakCanary: * references android.widget.FrameLayout.mParent 12-15 20:35:39.113 17227-20885/com.example.mapdemo D/LeakCanary: * references com.google.android.gms.maps.MapView.mContext 12-15 20:35:39.113 17227-20885/com.example.mapdemo D/LeakCanary: * leaks com.example.mapdemo.MapInPagerDemoActivity instance
Dec 15, 2015
One more slighlty different leak trace: 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: In com.example.mapdemo:1.0:1. 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * com.example.mapdemo.MapInPagerDemoActivity has leaked: 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * GC ROOT static com.google.maps.api.android.lib6.gmm6.h.q.j 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.q.f 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.g.g 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references java.util.ArrayList.array 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references array java.lang.Object[].[0] 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.m.cy.g 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.m.bf.k 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.c.y.mParent 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references android.widget.FrameLayout.mParent 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * references com.google.android.gms.maps.MapView.mContext 12-15 21:37:32.552 10110-11182/com.example.mapdemo D/LeakCanary: * leaks com.example.mapdemo.MapInPagerDemoActivity instance
Dec 15, 2015
With regards to your post #12:
> Are you seeing the same issue with the original code in MapInPagerDemoActivity? (Ie. using MapFragment directly?)
It sounds like it might be an issue in your custom Fragment. Are you forwarding all calls to super in the lifecycle callbacks?
Are you holding onto any maps-related objects in your fragment past its lifecycle?
That original code in MapInPagerDemoActivity doesn't apply here as it uses just:
"return SupportMapFragment.newInstance();"
i.e. there is no use of mapView in xml:
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Dec 22, 2015
Hello, is there any bug confirmation?
Attached is also a simplified version of the FragmentMap code along the #5, and #6 messages:
FragmentMap.java:
package com.example.mapdemo;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
public class FragmentMap extends Fragment implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener,
OnMapReadyCallback {
MapView mapView;
public static FragmentMap newInstance(int idx) {
FragmentMap fragment = new FragmentMap();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.pager_map, container, false);
mapView = (MapView) view.findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
if (args != null) {
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
}
@Override
public void onConnected(Bundle connectionHint) {
}
@Override
public void onConnectionSuspended(int cause) {
}
@Override
public void onConnectionFailed(ConnectionResult result) {
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
@Override
public void onResume() {
super.onResume();
if (mapView != null)
mapView.onResume();
}
@Override
public void onPause() {
super.onPause();
if (mapView != null)
mapView.onPause();
}
@Override
public void onStop() {
super.onStop();
}
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mapView != null)
mapView.onDestroy();
}
}
pager_map.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Leak:
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * com.example.mapdemo.MapInPagerDemoActivity has leaked:
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * GC ROOT static com.google.maps.api.android.lib6.gmm6.h.q.j
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.q.f
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.g.f
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.h.t.g
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references java.util.concurrent.CopyOnWriteArrayList.elements
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references array java.lang.Object[].[0]
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.m.cy.g
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.m.bf.k
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references com.google.maps.api.android.lib6.gmm6.c.y.mParent
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references android.widget.FrameLayout.mParent
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * references com.google.android.gms.maps.MapView.mContext
12-22 11:11:53.458 5081-6926/com.example.mapdemo D/LeakCanary: * leaks com.example.mapdemo.MapInPagerDemoActivity instance
Jan 5, 2016
Thanks for the report. Please let us know if there's any other details you can add. Have you been able to reproduce this on any other device than the "HUAWEI Y550-L01"?
Status:
Accepted
Labels: Internal-26413616
Jan 5, 2016
Issue 8155 has been merged into this issue.
Jan 20, 2016
Yes reproduced in Nexus 6, API 23 thanks to LeakCanary (https://github.com/square/leakcanary): * AAAAA.BBBBB has leaked: * GC ROOT static com.google.maps.api.android.lib6.gmm6.h.q.j * references com.google.maps.api.android.lib6.gmm6.h.q.f * references com.google.maps.api.android.lib6.gmm6.h.g.f * references com.google.maps.api.android.lib6.gmm6.h.t.g * references java.util.concurrent.CopyOnWriteArrayList.elements * references array java.lang.Object[].[0] * references com.google.maps.api.android.lib6.gmm6.m.cy.g * references com.google.maps.api.android.lib6.gmm6.m.bf.k * references com.google.maps.api.android.lib6.gmm6.c.y.mParent * references android.widget.FrameLayout.mParent * references com.google.android.gms.maps.MapView.mContext * leaks AAAAA.BBBBB instance * Retaining: 26 MB. * Reference Key: 1a047032-acb7-4ad7-993a-d066c7530128 * Device: motorola google Nexus 6 shamu * Android Version: 6.0.1 API: 23 LeakCanary: 1.4-beta1 02804f3 * Durations: watch=6283ms, gc=187ms, heap dump=8934ms, analysis=77315ms * Details: * Class com.google.maps.api.android.lib6.gmm6.h.q | static $staticOverhead = byte[16]@315894273 (0x12d42a01) |
|
| ► Sign in to add a comment |