I actually have a quick question which I cannot find an answer to.
I am VERY persistant that my Android/Java application eats up the least amount of RAM as possible as it helps the user experience.
With that being said my question is focused on field variables and the garbage collector.
My application will start up and I have a list of set field variables (hardcoded). Now for the sake of readability I have chosen field variables. If I wish to make a quick change I change the value instead of me looking through my code to see when the variable is actually used.
My field variables in this case are only used ONCE, when the application is loaded for the first time.
Does the garbage collector remove this variable or must I set it null manually. I know a simple int value isn't much to cry over, however I am curious as to the garbage collector.
The object which contains the field will always be in use (it will be an Android ViewPagerAdapter in this case).
Field variables are strong references; as long as that class object is around, the field variable must remain accessible. If you're only using them in one method, it'd be (marginally, slightly) more efficient to only keep them in scope for the run of that method.
In general you don't need explicitly set fields to null, however if you really concern about performance/memory avoid creating fields instead go for local variables i.e. Convert fields to local variable to method if possible and Avoid creating unnecessary fields if they used only once.
Best I would suggest for you is please refer to Android Best practices documentation for app performance improvement
http://developer.android.com/training/best-performance.html
http://developer.android.com/training/articles/perf-tips.html
Related
Is it better to use local or global variables?
Let's say talking about 2000+ lines of android(java) service class, and all service is working on 'request' object and similar shared objects.
If I make everything local(keep inside of function), I need to pass many variables every time, or override same function many times. I need to make sure that objects, and sub objects are not null too.
If I make some variables global(across the class) I can share them, use them across the functions. Which I think will make everything easier.
What are the good sides and bad sides of defining variables inside of function or defining globally. In practice, and in theory(readability etc).
Is there suggested way?
Thank you.
Always prefer local over global. If you need to pass the data in as multiple parameters, so be it. At least then you're explicitly saying what data your function depends on. Having too many parameters is certainly a problem, but offloading some of them as globals isn't the answer.
If you rely on globals, it may not be as clear where certain data is coming from. If the globals are mutable, you'll have a mess on your hands as soon as you start to try to debug a difficult problem since it may not be obvious when certain global variables are being modified.
Note though that immutable constant globals aren't bad. If you have a constant that's needed in many functions (like PI for example), it makes sense to make it global. Immutable constants don't suffer from the drawbacks mentioned above since they can't change.
You wrote a 2000+ lines of service class. You completed the project. Cool ! Now after a month, you got a bug reported and are required to fix it.
Lets go through 2 different cases :
CASE 1
You are back on the service code. You see that the func1() uses globalVariabl1. Okay, but whats its value by now ? How does it change ? Who mutates the globalVariabl1 before it comes to this function ? What have been the sequence of all these mutations ? You would have no idea. It will be quite difficult to figure all this out.
CASE 2
You are back to you code, and see that the func0() fetches something and then passes it to func1(param1) as a parameter. You clearly know what the data is, how does it gets here.
In what case will it be easier to resolve the bug ?
Most of the time, CASE 2 will make it lot easier.
Local variables
Local variables would always help you. Even when you write the code and using local variables, the call statement will itself tell you that this function depends on this particular data. It helps you to be careful about what you are passing around.
Global variables
Global variables are okay when they represent the state of the class/object, or even when they are Constant (which should in general be all UPPERCASE letters). They can also be good when you just need to access the value frequently, and you know that the variable will always be initialised when you use it (for example initialising it inside onCreate())
There are no global variables in Java. You are referring to member variables. The basic rule is that variables should have the smallest possible enclosing scope.
I know the question is already answered and I upvoted Carcigenicate's answer.
To elaborate on his point I would suggest you try Test Driven Development practices. As soon as you start writing your code in conjunction with Unit test you will realize how bad Global variables can be and you will realize that you are writing code that cannot be tested without having to implement unnecessary Dependency Injection.
One more thing. Global variables are a huge mistake any time you start dealing with multiple threads and concurrency. It doesn't sound like you are dealing with that but keep it in mind any time you decide to make a Global variable.
It all depends on the scope of the variable. If you feel that a certain variable will take multiple values by passing through various functions then use local variables and pass them in function calls.
If you feel that a certain variable you need to use will have constant value, then declare it as a global variable.
I'd like for efficiency sake to ask the following question. In, for example C you would declare a "global" variable if you wanted to re-use the same variable in functions over and over again without the added cost of converting it to a local variable (as that would require to re-initialize that variable when we call that function again).
In Java I am not so sure what would be best, have a local variable and re-initialize it over and over (maybe the optimizer is smart enough to remember it?) or declare it as a private variable separately inside the class? My gut tells me the latter should be better (and that is what I am currently doing) but I am not entirely certain that is the case.
Of course please exclude the multi-threading scenario where atomicity would be a thing.
I think that answer might help you. He wrote a micro-benchmark for determine the access speed of local and instance variables.
The result showed that local variable accesses are about 1% faster than instance variable accesses (even if both point to the same object).
Do not try to tune performance on such a low level. The performance of the resulting code depends heavily on the compiler anyways, but such a small "improvement" will not have any significant increase at all, as you are only talking about assigning a simple value to a variable, which does not take significant time to do (if we are talking about complex objects being created every call, that is obviously different, but your question was about initializing variables, so I answer that).
However, having a variable that is only relevant for a single function as a field of a class really hurts the readability and self-expression of your code, as the field is not relevant for an instance of that class at all.
Conclusion: If a variable is a local function variable, put it into the local function scope. If it is a field, put it as a field. Do not try to tune performance that way.
You cannot directly convert all you local method variables to instance variables. You ll break your code if you do so.
Instance variable are for specific purpose - which defines the state of an object. What you are asking can be solve by using static variables(probably final also - depending on the situation). If you use static variables - it ll be available for all the objects you create. But it will compromise with the thread safety as any object can modify it.
Private variable are accessible within the class while local function variable are accessible only within the function.
I'm a beginner with java programming and I have a simple question:
When should I use return values? I understand the meaning and what I can do with it. But I wonder if I shouldn't always make global variables to work with.
Can you guys tell me when I should choose which option?
The answer is GLOBAL values should be avoided as much as possible. The reason is global variable persists until the entire lifetime of that program. The GC (Garbage Collector) does not collect them until the program finishes(there may be some exceptions to this). But in contrast to this, local variables are eligible to be collected as soon as they fall out of scope. So the GC can collect them efficiently which leads to good memory usage.
So,
Generally, try to avoid using 'global' variables unless you have good reason to do so (e.g. the variable's contents are needed by more than one method in your sketch). This will help reduce the chances of inadvertently changing the contents of them in your code. So your second choice is one to avoid.
Some key points why NOT to use global variables:
It violates DATA ENCAPSULATION principle.
Lifetime is for whole program.
Messed up code if not carefully implemented
For example, if you have two copies of your program running in the same VM, will they share the static variable's value and mess with the state of each other.
Static variables represent state across instances which can be much more difficult to unit test. This is mainly because it is more difficult to isolate changes to static variables to a single test
I always read on the web that global variables are bad, and I understand that they are bad because each function has access to them and if each function in the application modifies the global variable, in a large application, it can become very difficult to trace the state of this variable at a particular point in the code.
But my question is this, if I have a variable that each function is going to need to use anyway, isn't it better to declare it as global? instead of having to instantiate my variable every time inside each function?
Also, when should I use global variables as opposed to local variables?
Every variable represents some real or imaginable entity. If you are sure that entity is unique, then it's OK to have static variable for it. For example, screen/keybord/mouse devices are represented with static variable of type java.awt.Toolkit (accessible via getter).
But such cases a rare. Usually, programmer thinks of single instance of entity, and declares a static variable for it, and then a need for another similar entity arise, which ends in laborious refactoring.
This is all about memory utilization while code is running.
You always try to keep less number of object into the memory while code running.Object with less scope(method scope) your object will live less in memory hence good memory utilization. So need to keep variable as less scope as it is necessary.
But your statement for global variable is not fully correct as in java we have access modifier (public,private,default etc) and if any global variable(class variable) has private modifier then it cannot be modified by outside the class.
"The Java language automatically initializes fields of objects, in contrast to local variables of methods that the programmers are responsible for initializing. Given what you know of intra- and inter-procedural data flow analysis, explain why the language designers may have made these design choices."
Its obvious to me that its to prevent a bug. However, what exactly is that bug?
Would it be to condense the possible control flow of some given method?
Could someone go into greater detail on this? I'd really appreciate the help.
It's really easy to do intra-procedural data flow, so it's really easy to check whether a field has been initialized and give warnings if it hasn't (one can write a simplistic decidable algorithm, e.g. make sure all branches of an if initialize a variable, and if one branch doesn't, fail, even if the branch is unreachable).
It's really hard to do inter-procedural data flow, so it's really hard to check whether a field of an object has ever been initialized anywhere in the code (you quickly get into undecidable territory for any reasonable approximation).
Thus Java does the former and gives compile-time errors when it detects uninitialized local variables, but doesn't do the latter and initializes an object's fields to their defaults.
It is not always the case that they are initialized. Objects can be instantiated without invoking any constructor by using reflections in combination with the class sun.misc.Unsafe or ObjectInputStream to access these classes private native methods or directly through JNI. These are intended for the purpose of object serialization/deserialization, and expect the fields to be populated by the deserializer. As for why the designers would have chosen to eliminate direct access to these methods(ie. without reflections) it stands to reason that pointers still left in memory could be used for stack-smashing or return-to-lib-c attacks. Clearing memory allocated for these "automatically" for most programs reduces the security risk as well as reducing the chance for errors. Also note that an attempt to read a local variable that has not been initialized results in a compile error for much the same reason