My app is crashing after longer use - runs out of memory.
I am closing all activities after switching to next one, but I still have that problem.
Is it possible to programmatically clear cache / memory, so application does not run out resources?
Can I use getCacheDir() to accomplish that?
Apparently your app is leaking memory. Make sure you clean up unused resources, close databases, reuse variables, etc.
Also refer to this post on how to track down memory leaks and how to avoid them.
Related
After painfully finding out that Typeface.createFromAsset can create memory leaks, I am trying to find a full workaround. The caching solution described in the above link helps to avoid having to reload fonts repeatedly while the application is running. But how about cases where your app has to start again from onCreate (e.g., after orientation changes, other apps popping up in between etc.)? Is there any way to store the typeface(s) in onSaveInstanceState in order to avoid having to call again Typeface.createFromAsset and leaking memory every time?
While going through the android developer site i found this .
it says to avoid memory leak we should release resources in onStop()but how to do so.
Basically any objects that are properly nulled are considered released and their memory can be reclaimed by the OS. Your question is too general and it's hard to offer a exhaustive list of methods, but you should generally be aware of these:
Stop/close any services/files/connections that you no longer need
Do NOT store any Drawable in any static Object, Drawables hold references to their owner View's which hold references to their owner Activity's, so if you hold on to any Drawable you will hold onto a lot of objects/memory unnecessarily
For an utility app, you probably needn't worry about memory; but for apps that use lots of Bitmaps, you should have a deep understanding of Bitmap management and how Bitmaps are used in your app in order to manage them effectively
There are a few notorious examples of memory hogs, with media (audio/video) and large bitmaps being the biggest memory hogs. Most things are taken care of by removing all pointers to them and letting GC have its way with them. Bitmaps, however, can be recycled more immediately by using:
if (yourBitmap != null) {
yourBitmap.recycle();
youBitmap = null;
}
Your media should be stopped and de-referenced. But it should be stopped in onPause(), and not left until onStop().
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
My android app is taking more and more memory over time. I took a heap dump and analyzed it with MAT.
Here's the main leak suspect :
So it seems like one of my activities isn't cleared from memory after I quit the app (with back button) then when I restart the app a new instance is created and fills in the memory.
Now if they're PhantomReferences why the memory isn't cleared after a while or when I quit the app? The memory is never cleared even when I use other app etc. The only way to completely close the app is to use a task manager to manually kill the app.
What can I do to avoid this anarchic memory consumption ?
EDIT:
I found the problem!
Each activity was setting up a CustomExceptionHandler with Thread.setDefaultUncaughtExceptionHandler() and that CustomExceptionHandler was keeping a reference to the context. So I got rid of the context reference and I 'nulled' the DefaultUncaughtExceptionHandler in the onDestroy() method. That's really better now!
I would use the dominator tree functionality of MAT to find out what is above those references, this may give you an idea of which Activity is the culprit.
Make sure you haven't passed a Context anywhere and held a reference to it, this is a classic android memory leak and it's really easy to do!
Although some static analysis tools frown on this, in the onDestroy() methods of your Activity you can null all your local variables (except primitives), it helps to nudge the garbage collector sometimes and can make for an easier to analyse heap dump in MAT.
Some generic approaches to reduce size of the app what I generally follow is this :
Call finish() below passing an Intent to next activity, this will avoid piling up of stack and helps in gc(garbage collection)
If you are not using shared preferences to save data, flush them at exit by calling System.exit()
If you find any drawable images/layout xmls/java classes which you are not using in your final program, ensure you remove them from the project
Images have to be .png since JPEG images take lot of memory.
In case of using database(sqlite, internal database etc), a better approach would be using "try/catch/finally" blocks, In try you open the db, in finally you close it, which will avoid memory leaks caused because of not closing cursors or databases.
Use AsyncTask instead of threads. in onPostExecute()function, close the progress dialogs if any.
hello friends
i have develop one application in which i have lots of images and sound,
i can release sound easily by release() method but i can't able to release image.
can you tell me how can i release image ?
earlier i have use system.gc() function but it is not working for image i thing it is garbage collector.
second thing is that can you give me precaution step against memory management (regarding of image,sound & codeing part also)
Thanks
nik
Invocations of System.gc() are only suggestions to run the garbage collector. The GC need not run immediately.
I believe such complex applications would benefit from using an MVC model. The Model (or logic) class can save the required images and sounds to a cache folder, and just pass the list of file paths to the view (Activity) which can read and display on-demand, de-referencing any assets that are no longer required.
Also, it would help to reduce the asset sizes (images and sounds) by lowering resolutions (image) or downsampling (audio), wherever possible.
Update:
- For downsampling images, check this link: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize
MVC is slightly tougher to implement in Android due to the fact that Activities are the entry points. So, what can be done is that a singleton "Model" object can be created, which can be accessed from anywhere. Similarly, a singleton "Controller" object can also be created. The activity can notify the controller when it requires an asset, and the controller will forward the request to the model.