Android - Many OutOfMemoryError exceptions only on single Activity with MapView

偶尔善良 提交于 2019-12-01 15:10:50

I downloaded the app and play with it while observing the memory via dumpsys.

Things look normal, memory gets reclaimed every time. I can't reproduce the situation, but I do see one spike that is probably related. Whenever you move around in map or zoom (basically refreshing the tiles) in satellite, there will be a brief spike in memory. If you do it fast enough, you don't give a chance for it to get reclaimed and it will go up.

Now, my phone is Android 3.3.4 and have pretty good configuration, so maybe the GC is much more efficient. I wonder though if my older test phones would reclaim the memory slower and thus when I get to the map (say after adding the fishes), I would still have memory from the previous activity that hasn't been reclaimed by GC. Then what I would do, I would go to my location and check things out by zooming in/out. That combined by previous memory from the previous activities might bring the phones to its limit.

This is just a theory though, I am on the road and don't have access to all my test phones. Do you know what version of the phones that are crashing? I'll be back 3-4 days later and I could try the app on my older phones.

UPDATED: I've run more experiments on this app. I'm almost sure that adding the fishes continuously will add more memories. I kept adding and deleting the fishes and checked that the memory keeps going up via dumpsys meminfo. A real users of the Pro Edition or even the lite who keep adding and removing the fishes might eventually hit close to the limit and going to the map afterward will trigger the out memory error since there is a memory jump going into the map. Here is the snapshot after I added and removed the fishes several times

** MEMINFO in pid 11572 [com.hookedroid.fishingcompanion.lite] **
                    native   dalvik    other    total    limit   bitmap nativeBmp
            size:    19728    18251      N/A    37979    32768      N/A      N/A
       allocated:    17174    14674      N/A    31848      N/A     3144        0
            free:      405     3577      N/A     3982      N/A      N/A      N/A
           (Pss):    12750     1771    25944    40465      N/A      N/A      N/A
  (shared dirty):      908     1544     5800     8252      N/A      N/A      N/A
    (priv dirty):    12732     1008    24208    37948      N/A      N/A      N/A

Your private memory jump to total of 37,948 which I am sure if I continue adding and removing fishes, it will throw the OutOfMemoryException eventually

MORE UPDATE (few minutes later): I manage to crash the app using the theory above. I must have added and removed fishes several times before it occurs. It could be more than 50 fishes before the app crashed.

My guess is the SQL somehow didn't get cleaned properly. Looking at the dumpsys after each set of adding and removing 10 fishes (which is the limit of the lite version), I see that

SQL
               heap:     6581         MEMORY_USED:     6581
 PAGECACHE_OVERFLOW:      173         MALLOC_SIZE:       50

 DATABASES
      pgsz     dbsz   Lookaside(b)  Dbname
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             33  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion
         1       16             62  FishingCompanion

The SQL memory keeps going up even though I deleted the fishes already. If I keep doing this for some time, eventually it will hit the upper limit of the phone and going to the map (which cause the jump in the memory) will trigger the out of memory exception seemingly indicating that the map page is the cause whereas I think that the add/remove fish page is part of the real cause (I say "part of the real cause" as I don't know if similar effect would occur say if I add new location).

I got the OutMemoryException right about when the total memory is about 58MB (this is probably different from phone to phone). For a reference, here is a similar OutOfMemoryException that I got:

D/dalvikvm(11572): GC_FOR_MALLOC freed 125K, 11% free 25734K/28743K, external 4047K/4695K, paused 188ms
D/AndroidRuntime(11572): Shutting down VM
W/dalvikvm(11572): threadid=1: thread exiting with uncaught exception (group=0x4001d648)
E/AndroidRuntime(11572): FATAL EXCEPTION: main
E/AndroidRuntime(11572): java.lang.OutOfMemoryError: bitmap size exceeds VM budget(Heap Size=28743KB, Allocated=25734KB, Bitmap Size=4047KB)
E/AndroidRuntime(11572):    at android.graphics.Bitmap.nativeCreate(Native Method)
E/AndroidRuntime(11572):    at android.graphics.Bitmap.createBitmap(Bitmap.java:695)
E/AndroidRuntime(11572):    at com.google.android.maps.ZoomHelper.createSnapshot(ZoomHelper.java:444)
E/AndroidRuntime(11572):    at com.google.android.maps.ZoomHelper.beginZoom(ZoomHelper.java:194)
E/AndroidRuntime(11572):    at com.google.android.maps.MapView$2.onScaleBegin(MapView.java:380)
E/AndroidRuntime(11572):    at android.view.ScaleGestureDetector.onTouchEvent(ScaleGestureDetector.java:216)
E/AndroidRuntime(11572):    at com.google.android.maps.MapView.onTouchEvent(MapView.java:682)
E/AndroidRuntime(11572):    at android.view.View.dispatchTouchEvent(View.java:3932)
E/AndroidRuntime(11572):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:955)
E/AndroidRuntime(11572):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
E/AndroidRuntime(11572):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)
E/AndroidRuntime(11572):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1015)

Hope it helps

i'm not sure if this is related to your issue.

this link disscusses about a memory leak issue and a proposed solution. based on that i'm using this version in my extended MyMapView and call this method in appropriate places.

public void cleanUpMemory(){
    try {
        Field fMapInView = MapView.class.getDeclaredField("mMap");
        AccessibleObject.setAccessible(new AccessibleObject[]{fMapInView}, true);
        fMapInView.set(this, null);
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        Field fConverterInView = MapView.class.getDeclaredField("mConverter");
        AccessibleObject.setAccessible(new AccessibleObject[]{fConverterInView}, true);
        fConverterInView.set(this, null);
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        Field fControllerInView = MapView.class.getDeclaredField("mController");
        AccessibleObject.setAccessible(new AccessibleObject[]{fControllerInView}, true);
        fControllerInView.set(this, null);
    } catch (Exception e) {
        e.printStackTrace();
    }

    try {
        Field fZoomHelperInView = MapView.class.getDeclaredField("mZoomHelper");
        AccessibleObject.setAccessible(new AccessibleObject[]{fZoomHelperInView}, true);
        fZoomHelperInView.set(this, null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!