Variable declaration inside for loop - java

Sometimes we found a reference type variable declared inside a for loop like this -
for(int i=0; i<1000; i++){
User aUser = new User(id);
//some other code
}
My question are -
1. Is there any decrease in performance for declaring a reference type variable inside a for loop?
2. Does the memory contains 1000 user object at a time?
Thanks in advance.

ThreadLocalHeap avoid acquiring heaplock for object allocation. It does not allocate large objects. It could allocate objects of size 512 bytes beyond that JVM do allocation on java heap which involves Heap lock. If the User object of < 512 bytes then there are less possibilities in performance degradation but anyhow all 1000 objects will present in the java heap.

Is there any decrease in performance for declaring a reference type
variable inside a for loop?
You will be creating new reference to point to a new object in this case. Even if you move the reference User aUser out of the loop even then it will lead to creation of 1000 objects but reference variable will not be created again and again. IMO you can move reference variable out but it may not cause big performance change as such. But when to use what depends. IMO if the reference variable is out of the loop it will end up pointing to last created Object in loop but if it is inside then all the references and objects to which they point will be ready for garbage collection.
Does the memory contains 1000 user object at a time?
Yes it may until they are all garbage collected by GC and when will it run we can never predict.

There may be a slight performance hit if you allocate a new reference for each iteration. It would be just as easy to declare User aUser; before entering the loop. However, I doubt the performance loss would be very noticeable, if at all.
The memory used by the variable aUser should be recycled after each iteration. This may not happen instantly (Java doesn't guarantee when garbage collection will happen)

Is there any decrease in performance for declaring a reference type variable inside a for loop?
Whenever new object allocated JVM acquires heaplock for doing allocation. Yes there might be slight performance
degradation because of repeated process of acquiring lock and release.
Does the memory contains 1000 user object at a time?
Yes Java heap will contain 1000 user object. GC will clean these objects if it does not have any strong outgoing/incoming reference to this object.

Related

Objects and pointers in Java

If you have that:
while(true) byte[] fillbuffer = new byte[400];
What will happen? Will create thousand of objects and each time just link the pointer of the fillbuffer with the new object's pointer? or something else?
Yes, then the old objects will be garbage collected as needed since they are no longer referenced. You can roughly see this yourself if you hook up VisualVM or similar and watch the memory usage (consider adding a sleep).
As pointed out, to be technical the array is the only object. You are allocating 400 bytes, and one object, whose main job is to know where the 400 bytes are, each loop.
I'm not aware of any optimizations that are done to avoid the allocations, but in general compilers/virtual machines in any language have a lot of license to take shortcuts. "Logically" my answer explains what happens here, but YMMV (specifically, YMMV depending on how much of the JVM spec you have read.)
If you are lucky, the Hotspot JVM will succeed at escape analysis and notice that the array never escapes the loop. It may then be optimized away altogether.
Escape analysis is a technique by which the Java Hotspot Server Compiler can analyze the scope of a new object's uses and decide whether to allocate it on the Java heap.
But at least for the first 1000 or so iterations - before optimization kicks in - it will likely allocate these, and eventually garbage collect them.
Congratulations, you have written an infinite loop.
What will happen?
Upon each iteration of the while loop, a new array of 400 bytes is allocated on the heap.
Will create thousand of objects and each time just link the pointer of
the fillbuffer with the new object's pointer?
Yes, a new array object is created each time. Since the variable fillbuffer is in scope only within the body of the while loop, the referenced byte array becomes immediately available for garbage collection upon completion of each loop iteration.
Edit: Note
If you were to define fillbuffer outside the loop, then its value would not be immediately available for garbage collection upon completion of each loop iteration, but the old value would become available for garbage collection as soon as the variable was assigned a new value. I.e.
byte[] fillbuffer;
while(true)
fillbuffer = new byte[400];

Where does return value go in java if no variable assigned to accept it?

Let's say a method returns some value, but when I call it, I don't assign any variable to accept this RV. Then where does it go? Will GC collect it? Would it be a problem if I use this kind of method tons of times in my code?
Then where does it go?
It doesn't go anywhere. The value / reference is simply discarded. It is as if you assigned it to a local variable that immediately goes out of scope.
Will GC collect it?
It will be garbage collected when the garbage collector detects that it is unreachable. In your example, the method doesn't put the object reference anywhere else, so it will be unreachable immediately.
Note that even if the object is immediately unreachable, it may take some time for the GC to notice this and collect it. (But that's not a bad thing. It is considerably more efficient to forget the object reference and deal with later than to try to reclaim the space immediately.)
Would it be a problem if I use this kind of method tons of times in my code?
Not necessarily. The example code is not doing anything useful, and hence the overheads of allocating the object and then garbage collected are simply a waste of resources. But if it was doing something useful, the overheads are not likely to be a problem. (In ideal conditions, allocating and garbage collecting an object is cheap in Java.)
Unnecessary allocation can be a problem in some cases though:
If you are running with a heap that is too small for the application's working set of objects, the overheads can ramp up.
HotSpot's default "throughput" GC will "stop the world" while the GC is running, so excessive allocations will increase the number o f GC pauses that you experience. (This may or may not matter ... depending on the application.) You can mitigate this by using CMS or G1 as your collector, but that introduces overheads in other areas.
Assuming the value isn't referenced anywhere else, it will be garbage collected
Will GC collect it?
Yes. Since there would be no live reference to the Object returned it would be eligible for GC.
Would it be a problem if I use this kind of method tons of times in my code?
It should not. All the returned Objects will be GCed.
There's nothing that special about a return value over a local variable, consider:
public Object example {
Object a = new Object();
return new Object();
}
Then if I briefly explain how return values work:
When a method starts a new "stack-frame" is pushed on to the stack. It is an area of memory that includes parameter and local variable storage including the return value. It also knows where to return to.
When the method executes, new objects are created on the heap and only pointers to them exist in the stack.
After the code for the method has been run the value of a non-void return method is passed back to the calling method and stored in it's stack frame.
If a non-void return method's value isn't required by the caller, then it will share the same fate as any other local variable in that stack frame. And that is it's value is no longer used. If that value was an object, then garbage collection is already aware of it and is now able to ascertain that it is not referenced and can be collected.

Java memory questions about 'new' keyword

What happens if you run the following code..
while (true) {
String x = new String("ABC");
}
in terms of memory?
Is String x allocated on the stack or on the heap? Will the program eventually crash because of a memory overflow, or will garbage collection prevent that? Does the new keyword always create the object on the heap? When is an object created on the stack?
Thanks!
Is String x allocated on the stack or on the heap?
x isn't a String. It is a reference to a String. The reference is a local variable, and so goes on the stack. The String is an object, and so goes on the heap.
Will the program eventually crash because of a memory overflow
Probably not.
or will garbage collection prevent that?
It should.
Does the new keyword always create the object on the heap?
Yes.
When is an object created on the stack?
Never ... unless the JVM decides it cannot escape the current scope and so decides to do so.
Using new, yes, puts objects on the heap. Objects that are no longer accessible by any thread can be garbage collected. Whether you run out of memory or not depends on the size of data your program uses, and if you are good at 'releasing' objects you dont need any more (think: memory leaks are bad).
In your example, you will be running the garbage collector like crazy, which I think is what you are intending to demonstrate.
Local variables go on the stack.
In theory, new creates on the Heap, and non-objects (i.e., ints, chars and so on) are created on the stack. The only exception, afaik, are strings, created on the stack as well. In practice, the JIT compiler of many modern JVMs will see that, in some cases, objects created with new can be created on the stack (for example, local objects that are not referenced outside of the current function).
The garbage collector will take care of the deallocation for you, that's its purpose, but of course you can run out of memory if you create and keep references on too many objects at the same time (try creating a list with a billion strings, for example).

Defining java object inside a loop , do I need to use null to free memory?

If I have a loop and create a new object inside it
for ( int i ; i < 10 ; i++)
{
MyObject obj = new MuObject();
obj.use();
}
Do I need to say obj = null, inside the loop at the beginning or end to release memory used by that object , or by using "new" that object will be send to GC ? and can I see this in terms of memory usage ?
update : so in case I have big object and long loop , should I assign the object to null or no ?
Check this: http://javarevisited.blogspot.com/2011/04/garbage-collection-in-java.html
"An Object becomes eligible for Garbage collection or GC if its not reachable from any live threads or any static references". After the loop ends, the objects that you created inside the loop do not have any external references pointing to them and are eligible for garbage collection.
EDIT:
If you want to see memory usage, you can profile your application using an IDE that has such a feature. For example, NetBeans has a nice interface that shows live memory usage for object allocation.
EDIT 2:
"so in case I have big object and long loop , should I assign the object to null or no ?"
No, you do not need to do this. Once one iteration of the loop is complete, there are no active references to any objects created in that iteration so it does not matter that you have a long or short loop.
Do I need to say obj = null, inside the loop at the beginning or end to release memory used by that object , or by using "new" that object will be send to GC ?
Neither, really. new only constructs new objects. When there are no references to the object, such as falling out of scope (i.e., not in the loop block), it will be eligible for garbage collection. Note that Java's garbage collector does not immediately collect objects - it does it in batches when it feels that it is required.
and can I see this in terms of memory usage ?
I would suggest looking at VisualVM, including with your JDK. It has a memory view, and a garbage collector view through a plugin.
Note that you cannot rely on the operating system "in use" count - the Java heap will rarely shrink especially if there aren't any major collections.
Nope, you don't need to set obj to null. When it is reassigned by the next loop iteration the previous reference will be garbage (unless something else points to it) and eligible for cleanup. That's the point of automatic garbage collection.
However there are some cases when you have to watch for things to control memory. If you have an static object pointer set it may never get cleaned up. (it's really not garbage since it has a live reference). One common issue is caches; it may hold unto old stale data that never gets cleaned up.
As it is even if you call the GC it will not do it immediately, but for good practice you can do so.
For memory management you can look into the features of IDE's like netbeans, Eclipse, etc.

Java Assignment Memory Leaks

I have to assume that the following method doesn't leak memory:
public final void setData(final Integer p_iData)
{
data = p_iData;
}
Where data is a property of some class.
Every time the method gets called, a new Integer is replacing the currently existing data reference. So what's happening with the current/old data?
Java has to be doing something under the hood; otherwise we'd have to null-out any objects every time an object is assigned.
Simplistic explanation:
Periodically the garbage collector looks at all the objects in the system, and sees which aren't reachable any more from live references. It frees any objects which are no longer reachable.
Note that your method does not create a new Integer object at all. A reference to the same Integer object could be passed in time and time again, for example.
The reality of garbage collection is a lot more complicated than this:
Modern GCs tend to be generational, assuming that most objects are short-lived, so it doesn't need to check the whole (possibly large) heap as often; it can just check "recent" objects for liveness frequently
Objects can have finalizers - code to be run before they're garbage collected. This delays garbage collection of such objects by a cycle, and the object could even "resurrect" itself by making itself reachable
Modern GCs can collect in parallel, and have numerous tweaking options
Java is a garbage-collected language.
Once there are no more live references to an object, it becomes eligible for garbage collection. The collector runs from time to time and will reclaim the object's memory.
In a nutshell, your code is 100% correct and is not leaking memory.
It gets garbage collected eventually.
if there is no ther reference to data, the garbage collector of java will clean the old data up and free the memory
Actually, since Integer is an object not a primitive type, the line:
data = p_iData;
is updating a reference.
Now, the old object that this.data used to point to will be examined by the GC to determine if there are no more references to that object. If not, that object is destroyed and the memory is freed (at some later time)
If the object previously referenced by data is no longer referenced by any object structure that is referenced from any running thread it is eligible for garbage collecion. GC is performed by Java in the background to free the memory of unused objects.
i want to show one example to you
in some code :
int x;
x=10;
x=20;
initially i assigned x to 10
again x to 20
first reference memory will be handled by Java GC.
Java GC is a thread tht run continuously and checked unreferenced memory and clean it .

Categories

Resources