I am not sure about one particular android optimization tip, that suggests to avoid unnecesary object creations. I'm unsure about thet "creation" part. In my application i started to assign several objects (context, resources etc) to activity fields with the intention to avoid calling the same get functions (getBaseContext(), getResources()) multiple times in each lifecycle.
So my question would be, when i assign those objects to activity fields, do i create new objects (and use extra space) or am i making a new reference to already created object?
When calling getBaseContext(), getResouces() you are not creating any new objects. You are obtaining objects that the Android OS has created whenever your application's process is first created.
And in regards to watching how many objects you create, I wouldn't worry about that at all unless you are creating a huge amount of objects (and I mean magnitude orders above 100s). 100s may even be too low.
A good practice would be too always keep your heap size in mind, if it you seeing it growing larger as you build your application, do your best to manage it. You can find out information about your heap size by looking at the DDMS (Dalvik Debug Monitor Server) view in your IDE.
Related
I have an application that requires data from a list in more than one classes extending Context. Sometimes I can pass the reference of the list to these classes and sometimes I cannot. So, I was wondering if putting the list to R.array.mylist and then continually calling from them in different classes might be a better idea? I specifically want to know if there is "high/low/acceptable"(in terms of memory & CPU) overhead to calling Resources continually.
Any suggestions/answers is appreciated. Thank you.
The "R" (resources) file is a static reference to XML defined objects. Creating a reference in XML allows you to reference those objects using objects that extend Context. It uses the Resources class to reference these objects.
If you inspect the source code (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/content/res/Resources.java#Resources) you will see it is essentially a handler for these XML defined classes. If you have access to Context then there are few steps you can take to improve upon a the short reference path that Context and Resources provide.
You can build your own mechanism for storing and/or referencing this array or you can use the one provided for you by the framework. Most likely you will find that the framework offers acceptable performance in terms of speed, memory allocation, etc. Since Context and Resources are loaded with your Application object, there is little overhead involved in using these tools. You will notice the source code attempts to optimize caching of XML objects, etc. That means the accessing and caching mechanism may not be optimized for some use-cases.
You may have situations where you can beat the effectiveness of the framework, but for most situations it is just fine. If you have a special use-case (like an array of 100,000 elements) then you might be able to optimize better than the framework. Most likely you will find that it is both convenient and effective to store your array as an XML defined object.
I'm thinking about using singleton patterns for adapters and helpers in an Android app that I'm building, but I'm not too familiar with Java's garbage collecting and how static attributes (eg static FooBar instance) impact memory usage.
Will it have a big enough impact in Android apps that I should avoid using it?
Depends on what you mean by "impact memory usage". An object isn't larger or smaller just because there is one instance of it enforced by a singleton pattern. In that sense there's no difference.
If it means you definitely have at most one copy of an object in memory instead of several, yes it could help.
Usually what people mean though, is, how long does the singleton live? does it stick around taking up memory when the app is in the background?
A static member is attached to an instance of its Class which is in turn attached to its ClassLoader. So the singleton lives as long as the ClassLoader. It turns out in Android that the app's ClassLoader goes away in onDestroy, not onPause, so a singleton implies you hold on to the memory even when the app is in the background.
As others have said, it depends. The case where it could be bad is if the singleton is holding references to objects that could otherwise be garbage collected. If there are a lot of references in the object, or references to large objects, you could be using memory you don't need. You could work around it by using weak references, but then you have to have code to recreate the objects when needed if they get garbage collected. You could not use the singleton pattern, which would allow things to get garbage collected (at least potentially), but at the expense of creating and throwing away objects. The best solution depends on the details of the object and its usage. One thing to always avoid is holding on to a reference to a UI object, such as a View.
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.
I was doing my 1st steps with android writing a money manager. It stores data in SQLite database and my approach was mostly procedural, while I was creating it.
It means: when I'm creating a chart or a summary it's look like this:
I create a database cursor
I iterate over that cursor to collect neccessary data
I pass the data directly to the element I need (a chart or listview for example)
Well, that works, but I'm learning more oop now and I'd like to rebuild my app.
I'm not fully aware of memory restrictions on mobile devices, that's why I'm creating this thread.
I came up with two ideas. Please tell me, which one you think is better (or correct my approach somehow if it's completly wrong).
Lets use an example of creating a chart or a listview like before. Now I'd do this that way:
I create database cursor.
I create number of objects equal to number of records I need to present data.
I use created objects to pass the data to chart or a listview.
This will require more code than my procedural approach but use of it should be much simplier then, and the code would has more 'proffessional' look (correct me if I'm wrong).
However, I got this dilema. Let's say I'm creating a set of objects based on data from table 'expenses'. I use them to present a chart or a listview on one of my activity. After I close the activity I don't need them anymore. What should I do to let garbage collector toss them away. Anything particullar? (yes, I'm new to the garbage collector stuff).
There is also second oop approach but I'm aware it will require a lot of memory and I'm not sure if it's a good idea at all. So, back to the example again:
I create cursors for each table I got
I create a set of objects matching the tables - basically I pass all the tables into set of objects for further use (I do it in a thread with some progress bar if necessary)
I use the created objects anytime I need to present my data.
Sounds silly, huh? I'm not sure when the garbage collector would dispose all those objects, and if it's a good idea to spam memory with that amount of data in once.
Thanks for any comments on this.
Both solutions work, but the first one is better because the objects are marked for GC as soon as they go out of scope, which happens much earlier than if they are kept for later use. Once the objects are GCed, the memory they occupied becomes available.
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.