LibGdx - Dispose Sprite or Texture in Sprite is mandatory? - android

I am loading my sprite with the texture from my assets like I have mentioned below.
gameBoardSprite = new Sprite( new Texture(Gdx.files.internal("data/gameboard.png")));
Do I need to have the below dispose in my code ? Is it mandatory ?
gameBoardSprite.getTexture().dispose();

Yes, dispose must be called on any Disposable object before you lose your reference to it or there will be a memory leak. The VM won't automatically dispose of the native memory used by OpenGL objects like Textures so you must manually do it before you drop your reference and let the GC claim the "non-native" memory claimed by the object itself.
If you are going to use a Texture for the lifetime of your app, you might not be planning to ever need to dispose it, but on Android you still have to in the Game's dispose method because there are cases where Android will shut down your Activity but not the entire Application so when the user reopens your game, all the previous textures are leaked.

Well technically you don't have to dispose it, BUT not disposing it WILL impact your performance.
On android Dalvik will kick in and decide whether or not to free up some of your memory. Thus causing frame loss.
On your desktop, memory leaks may happen.
Read here for more information

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".

How to release memory in android to avoid memory leak

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

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

Generic Android Garbage Collection

I don't want to create a vague question so I will try to make this as clear as possible (Going to try my best).
I know garbage collection has been a grey area in programming for a very long time. I am not certain with the case of android or other mobile phones.
What I know of garbage collection in android:
It collects class system class ojbects(Made by correction from an answer).
Edit* "GC collects activity items only once the activity is destroyed. Activity lifecycle is driven by its attributes in the manifest, also by the flags of the intent that that launched it." – Seva Alekseyev . As commenter said.
You may force a garbage collection using "System.gc()" although this is not recommended as it may delete something important class item.
Now I obtained this information from stackoverflow(Now knowing that it is no longer a grey area for garbage collection)
Going to my question:
How do you get this information about the process or generic information(book, internet article, etc.) about garbage collection from?
If there is not answer for question 1 what are the other ways or methods that developers should be reminded when developing applications requiring the constant use of memory?
I'm not sure your information is correct.
It collects class system classes.
No. It collects instances of objects that are no longer reachable from any of the system roots. System roots include any static reference, any reference from a thread's active stack frame, any active synchronization monitor, and anything held by a native piece of code (global or local). An object is considered live (and hence cannot be reclaimed) if there is a path from it to a root tracing the reference graph backwards. Any object that doesn't not have a path to a root can be reclaimed by the garbage collector. Classes are referenced by a ClassLoader and are never reloaded and hence are not reclaimed by the system unless that ClassLoader is collected and all instances of those classes are collected. So Android never collects class system classes because that ClassLoader is never collected.
It collects items from activity "only" if android manifest file states that the activity is either hasNoHistory or singleTop
No. An activity is nothing more than an instance of an object. And when the reference to the activity is gone so goes all of the references it pointed to unless some other root points to that object. By setting singleTop="true" you are only telling Android to instantiate a single instance of this activity, and all intents sent will be handle by that single instance. It doesn't have any impact on GC. When an activity looses its path to a root it will be reclaimed regardless of what the settings on that activity were.
You may force a garbage collection using "System.gc()" although this is not recommended as it may delete something important class item.
No Garbage collection algorithms do not delete any live object. Under your definition above it implies GC can collect an object you were using which is incorrect. If it did that's a big bug. That is also the beauty of Garbage Collection algorithms in that they are guaranteed to clean up garbage perfectly. If you are running out of memory the programmer has forgotten to remove a reference or you are being careless with your use of memory. The reason you aren't suppose to call System.gc() is that you/your program has no clue when the best time is to reclaim memory. The garbage collector is trying to maximize the ratio of (the time your program runs) vs. (the time it spends collecting garbage). It keeps very detailed statistics and makes estimations about when its a good time to run garbage collection vs simply allocating more memory.
It's like cleaning your house. You can't clean at all times because it makes doing things take longer sometime you have to let it get dirty (Like cooking). However, if you never clean your house it can take all day to clean it. So there is a balance that you must strike between how dirty can it become before cleaning it up takes longer than performing the task.
This is why you shouldn't calculate/guess/force GC in your program because Android has already implemented it for you, and will do a better job than you can ever hope to.
What does this mean for you the developer?
Let Android handle when GC should run.
Clean up references to help the GC know when something can be reclaimed. Be very careful about static references, and never allow a static to hold a reference to an activity, service, etc to one.
Don't allocate lots of small amounts of short lived memory. This will force more GC time to clean up. By allocating memory conservatively you are by definition helping that ratio.
Most of the time GC is very hands off. The only problems developers get into is not establishing boundaries for long living objects vs. UI objects. If a long living objects has a reference back to the UI that's a place you'll have to unregister or else you'll leak memory. It's ok for the UI to hold references to long living objects, but not the other way around.
The real issue with Android is how much you make the garbage collector work. If you keep the amount of memory you are using small then the garbage collector doesn't have big jobs it has to do. That doesn't mean you should reuse objects or create object pools, etc. But, you should be aware of what statements are creating memory, and how long those objects live for.
There are volumes of information on Garbage collection in general and particularly Java's Concurrent Mark and Sweep garbage collector. Android's garbage collector is not as performant, but it's pretty darn good. Most of the time I don't worry about GC unless there is a problem so it's mostly hands off.
And garbage collection isn't a grey area. It's very much well understood, and the industry has expanded the field quite a bit since Java was introduced in 1994.

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.

Categories

Resources