How to release memory in android to avoid memory leak - android

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().

Related

Importance of the dispose method (libgdx)

I'm just getting started with Android Game Development and I'm testing the libgdx Framework at the moment. I was just wondering what the importance of the dispose() method is and why it is necessary to dispose of every object there? Just to save resources?
Appreciate it.
Java is a "managed language". This means that everything (e.g. instances of classes or arrays) you use in your application automatically gets destroyed when you no longer use it. This is done by the "garbage collector". So, when you create e.g. an array (float[] arr = new float[1000];) then you allocate memory, but you never have to free that memory yourself because the garbage collector will do that for you when you no longer use the array (arr).
In some cases, however, the garbage collector can't know how to automatically free something for you. For example, when you allocate some space in video memory (VRAM) then you don't have access to that memory directly, but instead use the graphics driver to use that memory. For example (pseudo code):
byte[] image = loadImageFromDisk();
int vramId = graphicsDriver.allocateMemory(image.length);
graphicsDriver.copyToVRAM(vramId, image);
image = null;
...
// At this point the garbage collector will release the memory used by "image".
// However, the allocated VRAM still contains a copy of the image, so you can still use it.
...
graphicDriver.showImageOnScreen(vramId);
...
// The garbage collector can't free the VRAM though, you need to manually free that memory.
...
graphicsDriver.releaseMemory(vramId);
So, practically, there are two kind of resources in this case.
Resources that will be automatically released by the garbage collector. Let's call those: managed resources.
Resources that can't be automatically released by the garbage collector. Let's call those: native resources.
As you probably can imagine, libgdx uses quite alot of native resources behind the scenes. To properly manage those resources libgdx contains the Disposable interface. Every class that implements this Disposable interface uses (directly or indirectly) native resources that can't be released automatically by the garbage collector. Therefor you need to manually call the dispose methods on those classes if you no longer need them.
Not calling the dispose method can potentially result into problems with native resources. E.g. you might run out of available video memory or alike, causing your application to crash or alike. This is most commonly referred to as a "memory leak".

Is it a good idea to store LRUCache object in an Application singleton?

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

Destroy consume memory

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.

Is manual garbage collection in Android necessary?

While developing reasonably complex applications (e.g. accessing external resources such as files, database, network connections) on Android platform is it necessary to handle the Garbage Collection? Or should I let Android take care of GC all the time?
So does Garbage Collector relives an Android programmer from all burden of freeing memory?
If not, then can anybody explain with a practical example why is it so?
In general, GC helps programmers avoid many problems, but it is not a cure-all. As a programmer using a GC'ed system, you have two main things to worry about in terms of the allocation lifecycle:
Dropping references (e.g. setting variables to null) when objects are no longer needed. Failing to do so could result in a memory leak.
Explicitly managing non-memory resources, such as open files. The objects representing these things typically arrange to free up the resources when the objects get GC'ed, but as the programmer you may have a better idea about when the resource is truly unneeded. So, it is in your best interest to (say) explicitly call close() on an InputStream instead of just letting the GC clean it up long after it's no longer needed.

Drawable advantage over bitmap for memory in android

This question is linked with the answers in the following question:
Error removing Bitmaps[Android]
Is there any advantage of using Drawable over Bitmap in Android in terms of memory de-allocation ?
I was looking at Romain Guy project Shelves and he uses SoftReference for images caches but I'm unable to search where is the code which is de-allocating these Drawables when SoftReference automatically reclaims the memory for Bitmap. As far as I know .recycle() has to be explicitly called on the Bitmap for it to be de-allocated.
In my understanding, Bitmaps are typically better for performance if you don't need to do much image manipulation. However, I have run into memory leaks when I don't manually recycle them. My solution was to write a class to help me manage my images that provides an easy way to recycle all my bitmaps at certain points in my application. It also provides an easy way to reuse already loaded resources (including Drawables).
You don't need to call Bitmap.reycle(). This will be done for you in its finalizer. Doing it in the finalizer means the allocation will be delayed until finalizers run, so when possible directly calling recycle() can help with memory management.
Acc. to this page, starting from API Level 11, the Bitmap pixel data is stored in the Dalvik Heap along with the associated Bitmap. Thus calling .recycle is actually not required, unless you want to reclaim the memory manually for further use. Be sure to de-reference the bitmap too, just as an added measure.
PS: This was the link which explains hackbod's answer.

Categories

Resources