I'm new to android, so I don't have much experience with memory management. I don't explicitly cache any data myself, but for some reason my app uses a lot of cache memory. My app deals with a lot of bitmaps, so I can see why, but I don't know how to curtail this or keep it down. How do I restrict the amount of cache my program uses, and periodically clear the cache?
Related
I have this aplication thats keeps building cache every time I open the app
In my app I load like 20 images from my website, but I don't save them to cache,
does the app automatically save this images to cache? If so, I don't think they load from cache, cuz I still have to have internet to load them
Admob in the other hand, if I don't have internet and I loaded the test ad before, it will load the testad.
currently I have the app to delete the cache everytime it starts, keeping cache low, but this doesn't seems smart.
My questions are:
Does admob uses cache of my app?
Knowing my app loads 20 images from my website, this images being
loaded affects my cache size even if I don't save them
programmatically to cache ?
is deleting cache expensive enough to have a dedicated thread to
do just that?
Does admob uses cache of my app?
Yes i think Admob caches its ads so they load faster. And Admob should be managing its own cache size. I don't think you need to worry about that.
Knowing my app loads 20 images from my website, this images being loaded affects my cache size even if I don't save them
programmatically to cache ?
No images or bitmaps will not be cached unless you do so, see this link for more info. I will recommend that you use the Glide or Picasso for image loading since they are memory efficient and abstract out most of the complexity.
Is deleting cache expensive enough to have a dedicated thread to do just that?
I don't think you should use dedicated thread. What you can do is override onTrimMemory and keep monitoring the memory level.When your memory level is critical or low you can delete the cache. Check this link for more info. In my opinion if you use Glide for loading your images it will already handle the memory very well and prevents OutOfMemoryError. Also, loads image much faster.
I have an application that uses a sqlite database to present data about movies to the user. Each movie record in the database contains basically strings and integers.
Every time that the activity is re-created, the database is queried for the necessary "movies".
My question is the following:
If I were to create a LruCache when the app is launched to avoid querying the database each time, would there be a performance improvement? Would it be "significant"?
Although LruCache can cache anything, I thought that it would be helpful mainly for bitmap caching, as bitmaps are quite memory intensive. Is there any other situations in which it can provide a significant performance improvement?
Sorry for the ignorance, but I would really like to know well what this tool is for.
Thanks!
LRUCaches are really only useful when you need to only cache a certain number of things- for example with bitmaps you frequently create a cache of a fixed size so you only cache say 100MB of images, and everything else fails. THis allows you to avoid OOM issues (please note LRUCache isn't magical, you still have to code your app to use it correctly to get this advantage). The cost of it is that you'll preallocate most/all of that cache before its needed.
If you have something where the total memory used isn't 10s-100s of MB, you're better off just using a Map instead. Its quicker and easier.
As for LRUCache or Map vs Sqlite- yes, it would be quicker. If you have an anti-pattern like querying the database for every getView in a list, you should avoid that. But if you're querying for eveything up front and then saving it elsewhere in the application, repeating the query again for major things like a new activity/fragment is unlikely to be high cost. Also remember that an LRUCache is not persistent- it will need to be recreated from scratch the next time your app is launched. If you need to track changes or are trying to minimize server queries a local db is probably better.
I have a problem. I created the android app, when I start the app I see 48,09 MB cache memory. My app uses different libraries, has a lot of classes. I can't find a reason why the app uses so many cache memory? How do I find the problem?
Interesting thing: When I start an empty app, this app uses approximately 4Mb cache memory , I think it's too much.
I have an LRUCache that I use to cache thumbnails and other such small bitmaps. Currently, I'm using it in my main activity, however, I'd like to use it my other activities too. This makes me wonder if it's a good idea to simply store this LRUCache object in my custom application singleton (which extends Application) and solve the problem of accessing the cache in other activities. The reason why I'm concerned is because, as I understand it, if the application process is killed - which is very likely to happen when the app is left running for too long in background - the application object and therefore the cache will get garbage collected. Correct me if I'm wrong on that and help me understand this issue better/provide a solution to this problem.
My usual rule of thumb is, for persisted data use disk cache & for quick, dirty & light data, use memory cache (or your lru cache). Be careful with storing bitmaps in memory cache, at least for android devices < 2.3.3, I believe. The pixel data of the bitmap is actually stored in native memory so developers have less control to encourage garbage collections for it. For example, even setting your bitmap to null or invoking the recycle() method may not fully convince the garbage collector to free the bitmap in the dalvik heap (vm heap) since its a small object on the dalvik heap (vm heap), even though it's native counterpart in native memory is large cause OutOfMemoryException.
Sorry for straying off a bit but thought you should know. As for your the answer, your assumption is right. When android is running low on memory it retains the last user activity instance in it's system memory but may kill your process, where your process hosts your application object. So in your case, if you stored 5 bitmap objects in your application object, and users left for sometime, they may come back to an activity requesting a bitmap from a newly created application object by the system, which would then produce a null bitmap.
Given these circumstances the solution is typically clear. If you want to persist data, you can't trust object memory (in-memory, RAM), at least on Android, so disk memory might be your best option.
Hope this helps.
I think this is a perfectly fine idea. Here's a video from Google I/O 2012 with some relevant information: http://www.youtube.com/watch?v=gbQb1PVjfqM
I currently have my app caching image files in the cache sub-directory for the application. The images are used in a ListView and stored in a HashMap of SoftReferences to Bitmaps.
So my question is this, what is the best way to cache these image files without inflating the space my application uses AND remains responsive from a user standpoint.
Things I am concerned about:
I know the user can clear the cache and that it is done automatically when space is low on internal memory, but I feel most users will see a several MB app and uninstall it. Also if the space is constantly low, my app will just keep downloading the images, making it appear slower.
Most devices have an SD card pre-installed, but what should I do when it is not inserted? The SD card may also be slower compared to internal storage, affecting my app's performance.
Should I include an option to choose the location of the cache?
Should I attempt to manage the size of my cache (be it in the /cache or /sdcard) or just forget about it?
Thank you for your time (its a long one I know) and please post any relevant experience.
I can't offer you a comprehensive set of best practices, but I can offer what I've learned so far:
Managing your cache is a good idea. My app's cache is such that I know that I'll never need more than a certain number of cached files, so whenever I insert a new file into the cache, I delete the oldest files until I'm under the limit I have set. You could do something similar based on size, or simply age.
Caching to the SD card, if it's available, is a good idea if your cache needs to take up a lot of space. You'll need to manage that space just as carefully, since it won't automatically clear that space for you. If you're caching image files, be sure to put them in a directory that begins with a dot, like "/yourAppHere/.cache". This will keep the images from showing up in the gallery, which is really annoying.
Letting the user choose the location of the cache seems like overkill to me, but if your audience is very geeky, it might be appreciated.
I haven't noticed a much of a penalty when caching to the SD, but I don't know how your app uses that information.
Everyone has good ideas. I like the idea of using SoftReference's, although I'm not sure how often those get cleaned up, as this varies so much from VM to VM. You might want to combine that with regular HashMap to prevent you entire cache getting cleared every few minutes.
EclipseLink has a few different cache implementations and pretty good documentation on them. You could probably take advantage of a few ideas from the implementation (e.g., LRU, MRU, etc.). e.g.,
hard cache
soft cache
combined hard/soft cache
Since you're tuning a cache down to the nitty-gritty, I would recommend tuning it to different devices based on the hard specs. This is normally bad design, but the scope of the hardware that your software runs on mandates it, IMHO. e.g.,
Detect the amount of available memory on the SD card. Most new smart phones come with multi-GB SD cards, and those are pretty hard to fill up with regular usage for most users. Use away! You can also detect the amount of space available on the SD card on startup, and increase/decrease the size of your cache on startup.
Detect the amount of available memory and configure your caches with that in mind. If a user is using a hardware-intensive application, I don't think they'll mind that it makes up 200MB of RAM and provides a very fast user experience, especially since they spent a lot of money to have a phone that has 1-2GB RAM.
Good luck!
Should I include an option to choose the location of the cache?
IMO: No, let make it more simplest as possible (Except you can include advance setting for expert user)
Should I attempt to manage the size of my cache (be it in the /cache
or /sdcard) or just forget about it?
IMO: This is optional, it is double sword: your more work on background will help user more convenience but also more bug prone
Use 3rd libs:
IMO using 3rd library as Picasso is better, it handle cache automatically by order: Memory cache -> Disk cache -> Network