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];
Related
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.
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.
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).
In java, When we call a new Constructor(), then a new object is created each time i.e; a new memory is allocated or suppose there are already many objects created for a class that do not have any reference.
So can java return such object that are marked for de-allocation or will the java create a new object each time a new constructor() is called.
What's my basic intention to ask this question is if such thing happens then performance can be improved as the cost to create a new memory and destroying a un-refrenced object will be reduced.
Yes.
Java will never re-use an object.
Java always creates new object. Note that new operator is very fast in Java. There is no allocation, typical JVM will just increment one pointer on heap. Once heap is full, old and unnecessary objects are removed and live are compacted. But garbage collection is a different story.
Your idea is clever, but would actually worsen performance. JVM would not only have to keep track of dead objects (eligible for GC) which it is not doing. But also it would have to clean up the old object somehow, so that it appears to be fresh. That's non-trivial and would take a lot of time. new is both faster and simpler.
There is one catch, though:
Integer answer = 42;
42 is a literal that has to be converted to Integer object. However JVM won't simply call new Integer(42) but Integer.valueOf(42) instead. And in the latter case valueOf() sometimes returns cached values (it will e.g. for 42).
Yes, when you use new in Java, a new object is always created.
However, that does not necessarily mean that the JVM has to ask the operating system to allocate memory. How the JVM exactly allocates memory is up to the particular JVM implementation, and most likely it contains a lot of optimizations to make it fast and efficient.
Object allocation is generally considered a cheap operation in Java - usually you do not need to worry about it.
One example of a sophisticated optimization that's implemented in the current versions of Oracle's Java is escape analysis.
The cost of creating objects and destroying unreferenced object is trivial. What takes the time is
detecting when an object is no longer referenced. To do this every strong reference must be checked.
copying objects which are kept from one generation to another and defragmenting a generation.
finalising objects which implement the finalize() method.
If you create short lived temporary objects whether your Eden size is 8 MB or 8 GB, the time it takes to do a minor collection is almost the same.
There is a design pattern called flyweight, its main advantage is to reuse objects. Java uses that in creating strings itself.
you can learn more about it here: http://en.wikipedia.org/wiki/Flyweight_pattern
Wherever you see new(), you can be pretty sure that a new object is being created.. As simple as that..
In C++ we used sizeof() operator, which function can we use in Java to check the size of an object?
My basic doubt is that whether the reference variable in java has any size or not. Consider the following example:
SampleClass obj = new SampleClass();
Here, will obj have any size? If yes, How can we check it in Java?
obj is a variable, not an object. The value of obj is a reference - which is likely to be 4 or 8 bytes, depending on the JVM.
The size of the object that the value refers to is also JVM-dependent. As several objects can refer to each other, it's generally tricky to talk about the size of an object in Java in any particularly useful way... what usually matters is how much more memory would be potentially available if a particular object became eligible for garbage collection, and that depends on what other objects the first object refers to - and whether there are other objects that refer to those, too.
Obviously the "raw" size of an object is somewhat important too, and at least somewhat easier to predict (to an approximation, at least), but it's still VM-specific and can't easily be requested at execution time. (You could create millions of objects, prevent them from being garbage collected, and measure memory differences, but that's the closest I know of, at least outside a debugger API.)
Since you found my comment superb, I just had to post it as an answer, although it may be superflous to the already existing answers:
Rest assured that a reference variable (like obj) has a size, although there won't be a platform-independent answer on how large this size is, but there definitely should be a size. But due to this platform (or JVM) dependence, Java is not the language to mess with such low-level details.
Maybe the compiler can optimize some reference variables away as being just aliases for others, but in general obj has to have a size, as it has to somehow store the reference (whatever this is, it is something and not nothing).
obj is only the reference to an instance of SampleClass.
The size that the instance of SampleClass occupies in the memory depends on the elements the files of the object, and VM. But even a reference need some memory of course (like in c)
But the java memory model is much more complicated. If you are really interessted in how much memory the object need, then I strongly recommend to use a memory analyzer.
Anyway: because java is a VM and the Java VM has the garbage collector, there is no real 1:1 relation ship between the size of the memory you would expect by counting the (living) java objects and the memory the VM allocates from the Operation System.
You might try getting some insight on the "size" of the reference by using the freeMemory method of the Runtime class.
For example, allocate an array of 1000000 null references:
SampleClass[] array = new SampleClass[1000000];
Check the free memory before and after; the difference may give a hint on what you want to know (the array itself is an object, though its size is probably much less than 1000000, so the measurement must be pretty precise).