You create a variable to store a value that you can refer to that variable in the future. I've heard that you must set a variable to 'null' once you're done using it so the garbage collector can get to it (if it's a field var).
If I were to have a variable that I won't be referring to agaon, would removing the reference/value vars I'm using (and just using the numbers when needed) save memory? For example:
int number = 5; public void method() { System.out.println(number); }
Would that take more space than just plugging '5' into the println method?
I have a few integers that I don't refer to in my code ever again (game loop), but I've seen others use reference vars on things that really didn't need them. Been looking into memory management, so please let me know, along with any other advice you have to offer about managing memory
This question is related to
java
variables
memory-management
reference
garbage-collection
I've heard that you must set a variable to 'null' once you're done using it so the garbage collector can get to it (if it's a field var).
This is very rarely a good idea. You only need to do this if the variable is a reference to an object which is going to live much longer than the object it refers to.
Say you have an instance of Class A and it has a reference to an instance of Class B. Class B is very large and you don't need it for very long (a pretty rare situation) You might null
out the reference to class B to allow it to be collected.
A better way to handle objects which don't live very long is to hold them in local variables. These are naturally cleaned up when they drop out of scope.
If I were to have a variable that I won't be referring to agaon, would removing the reference vars I'm using (and just using the numbers when needed) save memory?
You don't free the memory for a primitive until the object which contains it is cleaned up by the GC.
Would that take more space than just plugging '5' into the println method?
The JIT is smart enough to turn fields which don't change into constants.
Been looking into memory management, so please let me know, along with any other advice you have to offer about managing memory
Use a memory profiler instead of chasing down 4 bytes of memory. Something like 4 million bytes might be worth chasing if you have a smart phone. If you have a PC, I wouldn't both with 4 million bytes.
In your example number
is a primitive, so will be stored as a value.
If you want to use a reference then you should use one of the wrapper types (e.g. Integer
)
So notice variables are on the stack, the values they refer to are on the heap. So having variables is not too bad but yes they do create references to other entities. However in the simple case you describe it's not really any consequence. If it is never read again and within a contained scope, the compiler will probably strip it out before runtime. Even if it didn't the garbage collector will be able to safely remove it after the stack squashes. If you are running into issues where you have too many stack variables, it's usually because you have really deep stacks. The amount of stack space needed per thread is a better place to adjust than to make your code unreadable. The setting to null
is also no longer needed
It's really a matter of opinion. In your example, System.out.println(5)
would be slightly more efficient, as you only refer to the number once and never change it. As was said in a comment, int
is a primitive type and not a reference - thus it doesn't take up much space. However, you might want to set actual reference variables to null only if they are used in a very complicated method. All local reference variables are garbage collected when the method they are declared in returns.
Well, the JVM memory model works something like this: values are stored on one pile of memory stack and objects are stored on another pile of memory called the heap. The garbage collector looks for garbage by looking at a list of objects you've made and seeing which ones aren't pointed at by anything. This is where setting an object to null
comes in; all nonprimitive (think of classes) variables are really references that point to the object on the stack, so by setting the reference you have to null
the garbage collector can see that there's nothing else pointing at the object and it can decide to garbage collect it. All Java objects are stored on the heap so they can be seen and collected by the garbage collector.
Nonprimitive (int
s, char
s, double
s, those sort of things) values, however, aren't stored on the heap. They're created and stored temporarily as they're needed and there's not much you can do there, but thankfully the compilers nowadays are really efficient and will avoid needed to store them on the JVM stack unless they absolutely need to.
On a bytecode level, that's basically how it works. The JVM is based on a stack-based machine, with a couple instructions to create allocate objects on the heap as well, and a ton of instructions to manipulate, push and pop values, off the stack. Local variables are stored on the stack, allocated variables on the heap.* These are the heap and the stack I'm referring to above. Here's a pretty good starting point if you want to get into the nitty gritty details.
In the resulting compiled code, there's a bit of leeway in terms of implementing the heap and stack. Allocation's implemented as allocation, there's really not a way around doing so. Thus the virtual machine heap becomes an actual heap, and allocations in the bytecode are allocations in actual memory. But you can get around using a stack to some extent, since instead of storing the values on a stack (and accessing a ton of memory), you can stored them on registers on the CPU which can be up to a hundred times (maybe even a thousand) faster than storing it on memory. But there's cases where this isn't possible (look up register spilling for one example of when this may happen), and using a stack to implement a stack kind of makes a lot of sense.
And quite frankly in your case a few integers probably won't matter. The compiler will probably optimize them out by itself in this case anyways. Optimization should always happen after you get it running and notice it's a tad slower than you'd prefer it to be. Worry about making simple, elegant, working code first then later make it fast (and hopefully) simple, elegant, working code.
Java's actually very nicely made so that you shouldn't have to worry about null
ing variables very often. Whenever you stop needing to use something, it will usually incidentally be disappearing from the scope of your program (and thus becoming eligible for garbage collection). So I guess the real lesson here is to use local variables as often as you can.
*There's also a constant pool, a local variable pool, and a couple other things in memory but you have close to no control over the size of those things and I want to keep this fairly simple.
Source: Stackoverflow.com