谷歌地图Android API v2 SupportMapFragment内存泄漏

使用2个简单的活动。 第一个Activity只包含一个按钮来启动第二个包含地图的Activity:

主要活动:

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void goToMap(View view){ //This is just the onClick method for the button Intent intent=new Intent( this, BigMapTest.class); startActivity(intent); } 

地图活动:

 public class BigMapTest extends FragmentActivity { SupportMapFragment mapFragment; GoogleMap map; @Override protected void onCreate(Bundle arg0) { // TODO Auto-generated method stub super.onCreate(arg0); setContentView(R.layout.travel_diary_big_map); mapFragment=(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.big_map); map=mapFragment.getMap(); } 

地图活动的XML布局:

   

现在当我运行这段代码时,按下按钮移动到带有地图的Activity,然后按回去进入第一个活动…然后重复这个过程,我可以看到堆每次都在增加,直到达到这是限制,然后开始钳制。 如果你用地图(即缩放)混乱一点,我可以在这一点上获得一个OOMexception。

01-25 16:10:13.931:D / dalvikvm(21578):GC_FOR_ALLOC释放1898K,7%免费45859K / 49187K,暂停204ms
01-25 16:10:14.671:I / dalvikvm-heap(21578):将目标GC堆从52.724MB夹到48.000MB
01-25 16:10:14.671:D / dalvikvm(21578):GC_CONCURRENT释放2534K,6%释放46554K / 49187K,暂停3ms + 14ms
01-25 16:10:15.372:I / dalvikvm-heap(21578):将目标GC堆从52.979MB夹到48.000MB
01-25 16:10:15.382:D / dalvikvm(21578):GC_CONCURRENT释放2273K,5%免费46815K / 49187K,暂停3ms + 15ms
01-25 16:10:15.622:I / dalvikvm-heap(21578):将目标GC堆从52.604MB夹紧到48.000MB
01-25 16:10:15.622:D / dalvikvm(21578):GC_FOR_ALLOC释放657K,6%释放46431K / 49187K,暂停202ms
01-25 16:10:16.203:I / dalvikvm-heap(21578):将目标GC堆从52.959MB夹到48.000MB
01-25 16:10:16.203:D / dalvikvm(21578):GC_FOR_ALLOC释放1469K,5%免费46796K / 49187K,暂停217ms
01-25 16:10:16.203:I / dalvikvm-heap(21578):强制收集SoftReferences以进行278744字节分配
01-25 16:10:16.423:I / dalvikvm-heap(21578):将目标GC堆从52.952MB夹到48.000MB
01-25 16:10:16.423:D / dalvikvm(21578):GC_BEFORE_OOM释放9K,5%释放46786K / 49187K,暂停219ms
01-25 16:10:16.423:E / dalvikvm-heap(21578):278744字节分配的内存不足。

任何建议/帮助将不胜感激。

接近我从一些基本的MAT调查中可以看出,你看到的是由Maps V2维护的下载地图数据的缓存。 如果平移和缩放很多,缓存似乎会更大。 如果您离开地图并稍后返回到新地图,缓存会缩小。 我无法在N次启动示例应用程序的地图活动时获得N个缓存,缓存大小根据用户的行为而消失和流动。

唉,这个缓存是不可配置的,AFAIK,它有多大,什么时候被清除,它是否溢出到磁盘等等。

因此,默认情况下,您所能做的只是留出一堆健康的堆空间,供Maps V2使用,并采取措施保持在这个较小的堆子集中。

如果您想进行实验,可以尝试在GoogleMap上调用clear() ,或者在SupportMapFragment上调用onLowMemory() ,以查看是否有任何帮助可以减少此缓存大小。

Android开发者下午5:10 – Google+页面

我们正在推出Google Play服务v3.0,它引入了Google+登录和Google Maps Android API改进。

截至2013年2月26日,此问题已在gmaps-api-issues页面上进行了描述,现在已由当前的Google API更新修复。

我也有完全一样的问题。 每次托管V2映射的活动开始时,内存都会增加。 即使活动结束,它也不会被释放。

因此,解决方法是重用该活动。 在manifest中创建活动singleTask而不是finish()它,使用moveTaskToBack(true);

在你的布局中使用它:

    

这段代码:

 onCreate{ setUpMapIfNeeded(); } private void setUpMapIfNeeded() { // TODO Auto-generated method stub // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map1)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } private void setUpMap() { // TODO Auto-generated method stub // Hide the zoom controls as the button panel will cover it. mUiSettings = mMap.getUiSettings(); // Enables/disables zoom gestures (ie, double tap, pinch & stretch). mMap.getUiSettings().setZoomGesturesEnabled(false); // Enables/disables scroll gestures (ie panning the map). mMap.getUiSettings().setScrollGesturesEnabled(false); // Enables/disables the compass (icon in the top left that indicates the orientation of the // map). mMap.getUiSettings().setCompassEnabled(false); // Add lots of markers to the map. addMarkersToMap(); // Pan to see all markers in view. // Cannot zoom to bounds until the map has a size. final View mapView = getSupportFragmentManager().findFragmentById(R.id.map1).getView(); if (mapView.getViewTreeObserver().isAlive()) { mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @SuppressLint("NewApi") // We check which build version we are using. @Override public void onGlobalLayout() { LatLngBounds bounds = new LatLngBounds.Builder() .include(WOODS) .build(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); } }); } } private void addMarkersToMap() { // TODO Auto-generated method stub // Uses a colored icon. mWoods = mMap.addMarker(new MarkerOptions() .position(WOODS) .title("Woods") .snippet("R. Quatá, 1016, Vila Olimpia - (11) 3849-6868") .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); }