Say I have class
public class OuterClass
{
public static WorkerClass worker;
}
In thread 1
The following command is executed
Outerclass.worker.doLongRunningOperation();
while the doLongRunningOperation is executed, in thread 2
Outerclass.worker = new WokerClass();
What will happen to the doLongRunningOperation in thread 1?
Will the worker Object referenced by thread 1 be garbage collected, only after the doLongRunningOperation is complete or can it be abruptly terminated to garbage collect worker Object.
Edit :
I think it should be GC'ed, since it is no longer referenced. But what will happen to the doLongRunningOperation? will it be terminated abruptly?
The Java garbage collector (GC) reclaims objects that are not traceable starting from a set of GC roots. That is, if object A is referenced by object B, and object B is referenced by object C, and object C is referenced by a root, then objects A, B, and C are all safe from the garbage collector.
So what are the roots? I don't know the complete answer, but I do know that the root set includes every local variable and parameter in every running thread.
So, if some local variable or argument in thread 1 still has a reference to the original WorkerClass instance, then the instance will continue to live.
The original WorkerClass instance will only be reclaimed when it is not referenced by any local or arg in any thread or, by any field in any traceable object. When that happens, it won't matter to your program any more because your program will no longer have any means to access the object.
P.S., "arguments and locals" includes hidden variables that are part of the Java implementation, and it includes implicit variable such as the this reference in every object method. Your original WorkerClass instance can not be reclaimed as long any method call on it (e.g., doLongRunningOperation) still is active.
Related
could you please help me?
I have a function 'f' in Java. The function works in multithreading environment
f() {
SomeObject someO = new SomeObject();
function1(someO);
.
.
.
function7(someO);
}
The problem: first thread enters into the function 'f' and creates new instance of SomeObject then calls function1, function2 ect. An instant later second thread enters into the method and creates new instnce of SomeObject when the first thread is in function4. The question is which instance of SomeObject will be processing by first thread in the rest of function 5, 6, 7 ?
The first thread has its instance of SomeObject (aka some0) as a local variable, therefore it is local to that stackframe and hence to that thread. It will only be able to reference that instance of some0.
Any other thread calling f() will create a different instance, also named some0, and only be able to reference that copy of it.
These are the rules for a local variable. If some0 were an instance variable -- i.e., declared outside f() -- then that variable could be referenced by different threads if they called f() on the same instance of whatever class holds the definition of f().
Those are the rules -- here's a more complete explanation.
Local variables are declared on the stack; that means that, for any variables declared within a method, there is space for their references in a 'stack frame' for that invocation of that method. Each time a method is invoked, there is space on the stack allocated for all the local variables in the method, and therefore their references are separate from any other invocation of that method. So if a different thread invokes the method, it gets a different stack frame for the local variables.
The same thing happens in a recursive procedure, i.e., if f() were to call itself. The local variable references would still be separate for each invocation of f(), i.e., each recursive call would have its own copy of them. Otherwise it would be very difficult to use recursion at all.
First thread will process first instance of SomeObject.
Every Thread creates its own stack. and whatever methods it is calling and whatever local objects it is creating, will live in that stack and these objects are not affected by other thread. So in your case thread 1 one processing is not going to affect by thread 2 processing.
One of the few things I know about Garbage collector is that it picks up the object which have no references.
Let MyClass is a class and I make an object of it by doing
MyClass object = new MyClass();
I can make it eligible for garbage collection even when my code is executing by doing
object = null;
But what happened to the objects which have no object references, like following statement.
new MyClass();
My doubt is really concerned to threads, I can create and execute a thread by following code.
public static void main(String args[])
{
new Thread() {
public void run() {
try {
System.out.println("Does it work?");
Thread.sleep(1000);
System.out.println("Nope, it doesnt...again.");
} catch(InterruptedException v) {
System.out.println(v);
}
}
}.start();
}
But the thread is having no reference to it, like you know I can create thread by having a object reference but May be I don't want to.
Let the thread is doing a long long running Task, How the garbage collector will react to this?
What will happen to the new MyClass(); statement from the perspective of GC...
GC looks at all live threads for stack traces so your Thread doesn't have a reference from the main thread, but it does from the currently executing one (the newly created thread).
GC looks for the reachable objects from so called GC roots, one of the roots are all threads.
...object which have no references...
Let's just be clear about what that means. Discussions about GC often distinguish objects that are traceable from a GC root from objects that are not traceable.
"Traceable" means, that you follow a chain of object references starting from a gc root, and eventually reach the object in question. The gc roots basically are all of the static variables in the program, and all of the parameters and all of the local variables of every active method call in every thread.
"Active method call" means that a call has happened for which the corresponding return has not yet happened.
So, if some active method in some thread has a reference to a Foo instance, and the Foo instance has a reference to a Bar instance, and the Bar instance has a reference to a Baz instance; then the Baz instance is "traceable", and it won't be collected.
In every thread, there are method activations below the run() call on the thread's stack, and at least one of those method activations has a reference to the Thread instance that manages the thread. So a Thread object will never be GCd while the thread that it manages still is running.
Also, somewhere in the dark heart of the JVM, there's a static list of all of the Class instances, so none of them will ever be GCd either.
The JVM keeps a reference to all the running thread so if a thread is running it will not be garbage collected. Also if your object is referenced by a running thread it would not be garbage collected.
when does instance variable of a static method gets memory in java?
it is perfectly right to create instance variable in static method (either in parameter or declaring inside the function), but i want to know when does the instance variable of static method is allocated memory, if no object of the class is created?
Actually i meant to say the local variable inside static method
Firstly, the term instance variable is not accurate, I am assuming that you are asking about local variable such as a and b in the example below:
void method(int a) {
int b = 3;
}
In Java, only primitives and references are stored on stack, objects are stored in heap when they are constructed. Stack will be cleaned as soon as the scope ends, heap is cleaned by garbage collector.
Here is an example:
public class Main {
static A a = new A();
static void method() {
int b = 2;
C c = new C();
}
}
The first time your code refers to Main, class loader will load the class and initialize all its static fields - object new A() will go into heap. Nothing more happens here, method method could as well not exist.
When you call method method, it will add value 2 on the stack, then it will add reference c on the stack which will be pointing to the object new C() in the heap.
When method exists, 2 and c are removed from the stack (there is actually no removal, but the top of the stack is changed to two positions below so these two values will be overriden whenever something else comes onto stack), while new C() will remain in heap until garbage collector triggers. It's likely that it will be garbage collected immediately as GC may detect that there are no more references to this object.
If you declare a variable or use parameter inside a static method, its not at all instance variable. Its a local variable and it will be initialized once the method gets invoked
static void methodTest(int i) {
String s = "Hello";
}
Here s is a local variable to that method.
and i is the function parameter which is also a local variable to the method
There is not such thing as an instance variable in a static method.
If you mean parameters and local variables, those are allocated on stack (any created objects being allocated on heap as usual).
Static fields of the class will be initialized when the class is loaded.
Instance variables of a class will be allocated (and possibly initialized) when an instance is constructed.
The variable defined by static method is still local variable in scope of the method, just as if non-static method created local variable. However, problem is that the variable never gets garbage collected, as long as the class loader (usually main class, which gets "unloaded" only at runtime termination, which is like scratching your left ear with your right hand) is not unloaded and garbage collected. And objects get GC'd only if they are not referenced anymore, and in case of static fields, they have tendency to be referenced even when nothing uses them because of the behavior I described. So in large applications, where memory and resources are issue, it is pretty bad idea to declare anything inside static methods since you pretty soon pollute the memory with LOCAL VARIABLES that cannot be collected.
In the code below, given that amethod has been called. At what point/line is the Object originally referenced by myObject, eligible for Garbage Collection?
class Test {
private Object classObject;
public void amethod() {
Object myObject = new Object();
classObject = myObject;
myObject = null;
}
}
And if classObject or amethod had an access modifier of public, protected, default or static, would it affect what point the Object is eligible for Garbage Collection? If so, how would it be affected?
My first thought is that the Object is eligible for Garbage Collection when the Test object is eligible for Garbage Collection.
But then again. The optimizer may know that the classObject is never read from in which case classObject = myObject; would be optimized out and myObject = null; is the point it is eligible for Garbage Collection.
The object will not become a candidate for garbage collection until all references to it are discarded. Java objects are assigned by reference so when you had
classObject = myObject;
You assigned another reference to the same object on the heap. So this line
myObject = null;
Only gets rid of one reference. To make myObject a candidate for garbage collection, you have to have
classObject = null;
From Book OCA Java SE 7
An object is marked as eligible to be garbage collected when it
can no longer be accessed, which can happen when the object goes out
of scope. It can also happen when an object’s reference variable is
assigned an explicit null value or is reinitialized.
This is actually addressed precisely by the Java Language Specification, §12.6.1, Implementing Finalization :
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
Another example of this occurs if the values in an object's fields are stored in registers. The program may then access the registers instead of the object, and never access the object again. This would imply that the object is garbage. …
But
… Note that this sort of optimization is only allowed if references are on the stack, not stored in the heap.
For example, consider the Finalizer Guardian pattern:
class Foo {
private final Object finalizerGuardian = new Object() {
protected void finalize() throws Throwable {
/* finalize outer Foo object */
}
}
}
The finalizer guardian forces super.finalize to be called if a subclass overrides finalize and does not explicitly call super.finalize.
If these optimizations are allowed for references that are stored on the heap, then a Java compiler can detect that the finalizerGuardian field is never read, null it out, collect the object immediately, and call the finalizer early. This runs counter to the intent: the programmer probably wanted to call the Foo finalizer when the Foo instance became unreachable. This sort of transformation is therefore not legal: the inner class object should be reachable for as long as the outer class object is reachable.
This example can be applied 1:1 to your example, as long as the object is referenced by the instance field classObject, it can not get garbage collected earlier than the Test instance containing the reference.
Note, however, that the aggressive optimizations mentioned in the specification are still allowed, when being applied to the code using the Test instance. The earlier-than-expected collection may happen, as long as both, the Test instance and the referenced object are collected together. In this case, the following aspect specified in §12.6 applies:
The Java programming language imposes no ordering on finalize method calls. Finalizers may be called in any order, or even concurrently.
So it’s perfectly possible that the Test instance is collected earlier than the object referenced by classObject whereas the “inner” object’s finalizer is invoked earlier. The only thing that is guaranteed, is, that when the inner object’s finalizer runs, the outer object is unreachable (or has a pending or concurrent finalization). Since in your example, neither has a non-trivial finalizer, that doesn’t matter anyway…
Your idea that the private object may be GC'd right away because no other code is able to access it does have some traction, but this would mess with the general semantics of Java memory management. For example, if that object implemented finalize, and Java semantics clearly dictates when an object is eligible for garbage collection, that finalizer method would be have to be called against the specification.
Also note that the object in turn may reference other objects, with even more complicated possible outcomes. Not to mention the object is reachable by Reflection anytime and it would make no sense for the field to be observed to suddenly change to null even if no code could have made that assignment.
To conclude, there are many reasons why your idea of optimization would not work in the wider picture.
No object is eligible for garbage collection here because you are creating two reference for the same object and you are giving null to only one reference but other reference is still pointing your object
Since you are holding myObject in classObject(reference is maintained), it(object in memory referenced through classObject) will not be available for Garbage collection until instance of Test is freed up/unloaded.
In the code below, given that amethod has been called. At what point/line is the Object originally referenced by myObject, eligible for Garbage Collection?
Your question is nonsensical because there is a disconnect between your high-level source code and the low-level representation (global roots in registers, on the stack and in global variables) that the garbage collector sees.
Your phrase "eligible for garbage collection" presumably means at what point does a heap-allocated block of memory become unreachable. So your question can only be answered by making a lot of (dubious) assumptions about what heap allocates and how long the generated code will keep references.
While reading on Thread Safety I came across this issue.
If I'm correct method local Primitives and object references lives inside a stack and actual objects pointed by the references inside the stack lives in the heap.
But when it comes to method local non primitive object initialization, wouldn't that cause a concurrency issue ? I mean if the method locals non primitives lives in the heap and only the pointers lives in the stacks, isn't it the same as of instance variables ?
Can someone please help me to understand this....
PS
Think of two threads with each having two stacks of their own and one heap. What I understood is that the two threads keep their method local primitive variables inside their stacks. I have no issue with that.
But what if we have a method with non primitive method local variables ? Then if the object for that variable is stored inside the heap, both the threads will have the access to the same object, won't they ? So if that's the case there would be Sync problems.
That is what I'm asking.
Thanks
But what if we have a method with non primitive method local variables
? Then if the object for that variable is stored inside the heap, both
the threads will have the access to the same object, won't they ? So
if that's the case there would be Sync problems.
I wonder why you will think the two references will refer to the same object.
The creation of the object referred is explicitly done by new (or other similar method, but idea is the same)
Therefore, unlike in C++, if you are declaring this in Java
Foo foo;
there is no Foo object instantiated. foo is just a pointer pointing to nothing.
This will create you a Foo object instance in heap.
Foo foo = new Foo();
If two thread is running this piece of code, thread 1 will have a Foo reference in stack, and ask to allocate a new Foo object in heap, and then assign the address of that Foo obj to the reference foo. Thread 2 is doing the same. Note that Thread 2 is also asking to allocate a new Foo object, it will be a different object from what Thread 1 is allocated.
That's the basic (and much simplified) idea.
Both threads could have access to the same object if they both have a reference to the object. If you have a method like the following:
public String concat(String a, String b) {
StringBuilder builder = new StringBuilder();
builder.append(a);
builder.append(b);
return builder.toString();
}
The StringBuilder object is indeed in the heap, but only one thread has a reference to this object. No other thread can have a reference to this StringBuilder. So it's inherently thread-safe.
If, on the contrary, you have the following:
public String concat(String a, String b) {
final StringBuilder builder = new StringBuilder();
new Thread(new Runnable() {
#Override
public void run() {
builder.append("haha!");
}
}).start();
builder.append(a);
builder.append(b);
return builder.toString();
}
Then you have a thread-safety issue, because you shere the locally created object reference with another thread, and StringBuilder is not thread-safe.
But what if we have a method with non primitive method local variables ? Then if the object for that variable is stored inside the heap, both the threads will have the access to the same object, won't they ? So if that's the case there would be Sync problems
You partially answered your own question.That reference value is stored in the stack but the actual object content is stored in heap and when you call new Object() each thread creates different new object that will be stored in the heap and each thread access the object it has created using the reference value stored in its own stack
Local variables are either primitives, references to objects created somewhere else (if you do an assignation), or references to newly created objects (using "new" operator)
For the first case, as you said, there is no issue.
For the last case, as you are locally craeting a new object, a new object will be created at every call, so no concurrency issue because there will be one object in the heap for each call
But for the second case, as the object has been created somewhere else, you have to think about concurrency
Just to toss in my thoughts regarding what may be your point of confusion: the heap is not managed like the stack. It is shared, yes - in that objects created by all threads are in the heap. However as each object is created, it's given a unique location/space in the heap. Two methods on two threads running concurrently and creating an object instance will create distinctly different objects in the shared heap.
They're created in this shared heap so that if method foo returns the object reference, or stores it, or calls another method that indirectly stores it... it won't be destroyed when foo returns and the stack is popped.
The magic of having a garbage collector is that you don't have to keep track of this "stuff" and destroy it yourself at some appropriate point in the future. Keeps your code simple, lets you focus on algorithms (or learning to program). But I digress...