I'm auto-testing my app by loading the same screen over and over. I make heap dumps every 400 screen loads and then try to see whether I have leaks. The screen makes 3 network calls (it loads two XML files and one bitmap file). I noticed this object:
39 instances of "org.apache.http.impl.conn.tsccm.ConnPoolByRoute", loaded by "" occupy 6,506,440 (51.72%) bytes.
This is after 800 screen loads. The "funny" thing is that after 400 loads there were 75 instances totaling to about 13MB!
In fact, the strangest thing is, that the heap keeps increasing from 12MB to almost 27MB (I'm not sure if it will go over the 64MB that the device has!). When I stop the automatic loading and repeatedly press "Cause GC" in the Eclipse DDMS Heap section, it keeps drecreasing the "Allocated" memory until I'm almost down to 6MB!? The question I have is, how come the heap size keeps increasing even though it seems I'm not using all that memory. Is it because my memory is defragmented? Should I be able to converse more memory if I don't keep creating new objects but keep an object pool? Should GC not cause an OOM when I reach the critical value of 64MB and should it try to do its best more? I feel kind of uneasy that it would get so close to 64MB. I wish the GC would be more punctual :)
Hope someone can help.
Best,
Joris
Related
I am planning to hunt any memory leak in my Android App. After searching through different blogs, it seems like MAT is a good tool for that.
Before proceeding further, I just want to make something clear. When I check allocated heap memory in memory monitor tab of android studio, i can see the allocated memory increases by ~1 MB (from 16MB of initial allocation) each time I rotate my device. This, most probably suggests some leaks.
However in the process, at any stage, whenever I click on Garbage Collection button in memory minitor window to force GC, the allocated memory comes down to near the initial stage 16MB+ (sometimes requires 2 back to back click when allocated memory expands beyond 30 MB).
My question is, does this behavior suggests that I don't have any leaks due to strong references? If GC can collect those extra chunks, how important is that to check the issue?
OOM happens when the heap gets full. But what if we increased the size of the RAM of the device, will that help prevent OOM?
I tried to look at tutorials on how to prevent OOM , which recommended multi-threading and trimming down the size of the bitmap. But I still get OOM errors.
But what if we increased the size of the RAM on the device, will that help prevent OOM?
Yes and no. The answer is "it depends on why you are running out of memory."
If you are trying to manipulate a 2GB Bitmap on a 1GB device, then yes, adding a few extra GB of RAM will solve your problem.
If you have a rogue operation that is constantly allocating new Objects, then adding additional memory will just delay the OOM Exception. Extra RAM is not a long term solution to poor memory management.
You need to work to identify why you are running out of memory first. If the issue is that you really do need more RAM (which is fairly unlikely), then go ahead and add more. If the problem is that you are unnecessarily allocating memory or leaking objects, then fix those problems first.
With Bitmaps specifically, you often don't need the full quality image. If your image is stored at 1080p resolution but the device is only a 480p screen, then loading the entire image into memory is a waste of space since most of the image won't be used anyway.
I'm testing my application's memory usage on the emulator. And the problem is that on the emulator the app heap is just growing and growing, just a little bit of resources are freed. And if no collections are made it will cause an OutOfMemory exception on big resolution screens.
I downloaded the Sony SDK and there is an emulator configuration for the Xperia Z that has 1080x1920 resolution and the default heap is 64MB. I think it's a small heap size for that resolution because my app uses 40MB only starting up. However on my phone it's using 15MB of 64MB (res. 540x960).
So this quite small heap size (might not be real?) + GC behavior is causing OutOfMemory quite fast.
On a real device (I've tested only on mine), GC is working very nicely, it's freeing resources that are no longer used, but I really cannot predict if that will work on other phones.
Should I ignore how GC is working on my emulator or might it be my app's problem?
Growing heap on emulator indicates that at some point you have memory leak.
They are very common when you send intents between different applications ( e.g select image from gallery) . Most of device can handle such leaks with no problem.
Another reason for heap to grow up: inefficient memory operations. That means at some time you are asking to much memmory ( e.g you selected 5M image from gallery, created inpuststream for it and keep in memory as bitmap, so you asking 15+M emulator will show just hight heap grow, but most of devices will show error).
If you see heap grows - analyse your memory usage and detect leaks. Link
If you dont detect anything strange you can almost safely ignore heap warning.
Note: heap show supplied space, not used.
I'm working on an app to streaming music from internet... My app does many things and it's structured in this way: I have a tab view and every view is allocated in memory so every time I navigate through tabs I find again the previous status ( every tab can also open a webview to find information about songs, news etc in internet ).. all that grows memory occupation but makes the app very user friendly... After having paid attention to avoid memory leaks following the Android guide, I tried to look at the heap occupation and I found that my app allocates max 3.5MB of memory and the heap size allocated is 4.5 - 4.6 MB... I'm working on the emulator .. They are not so much I think, but sometimes my app is restarted founding in LogCat a strange message like
Grow heap ( frag case ) to 3.373 for 19764-byte allocation
What is it? an emulator issue? or something else? Am I using too much memory?
Thank you in advance for any help :)
The maximum heap size depends on the device (you can get that value by calling Runtime.getRuntime().maxMemory()), but it's probably around 32MB. In order to save memory, Android doesn't allocate maximum memory to every app automatically. Instead it waits until the app need more memory and then gives it more heap space as needed until it's reached the max. I believe that's the Grow heap message you see.
If you do a lot of memory allocation and freeing, you may run into fragmentation problems. Wikipedia has a decent description here, but basically means that you might have the required memory available, just not all in one chunk. Hence the need to grow the heap.
So to answer your questions, it's probably not an emulator issue, it's just the nature of your program, which sounds a little memory heavy. However this isn't a bad thing. I don't think using 3-5MB for multiple tabs with webviews is too much.
So, for my particular application, I have a pretty large list of items in my ListView, upwards of 10,000+ items. I don't keep all the items in memory, but rather I lazy-load them around 150 at a time from a database. I'm using an LRU cache to only keep the last 500 or so items around, but the problem is that even so, sooner or later I run into memory issues.
This error eventually starts spamming my Logcat when I move around the list view:
03-15 12:36:45.114: ERROR/dalvikvm-heap(8971): 86400-byte external allocation too large for this process.
03-15 12:36:45.114: ERROR/GraphicsJNI(8971): VM won't let us allocate 86400 bytes
Once I get into this state, if I click on an item to go to the next info activity, it'll crash with an OutOfMemory exception. Before this, it's perfectly fine and can go into the info activity just fine.
Looking at my memory usage in DDMS, the heap size is only around 6, and actual usage is only around 5mb when the errors start popping up. The info activity does contain some images and stuff, but definitely not an extreme amount, and only bumps up the usage by like 100kb or so. This is no where near the usual 16mb heap limit that I've heard tossed around.
Any ideas?