Is this still WeakReference? - java

I am creating a WeakReference and keeping it somewhere.
WeakReference<MySpecialObject> mWeakReference = new WeakReference<MySpecialObject>(new MySpecialObject("My","Special","Data"));
But some other external library(which I don't what it is doing it) really needs MySpecialObject instance. When I used something similar below:
ExternalLibraryThingy#useItWisely(mWeakReference.get());
end of part #1
after some time I do call
ExternalLibraryThingy#doSomethingUsefull(); //which I dont know it kept a reference while calling "useItWisely" method.
end of part #2
Question
Until the end of part #1, is my in place created MySpecialObject object still weakly referenced? I mean if I call mWeakReference.get(), is there any chance of getting null? In other words can OS garbage collect it at will?
Until the end of part #2, if the ExternalLibraryThingy made and assignment while useItWisely and using that assigned value while doSomethingUsefull, can it throw a NullPointerException?
I guess one simple answer can be the answer for both of the question. Thanks in advance.

You passed the dereferenced object to the ExternalLibraryThingy#useItWisely method. The external library does not care that you retrieved the object from a weak reference.
So whether the object has strong references in the external library depends entirely on the method that you called on it. Without knowing what the method does, it is impossible to know whether the object will still be referenced.
As for your second question, the library had the MySpecialObject reference directly. From the point of view of the external library, it is not going to be randomly replaced with null.

Related

Anonymous variables (?) advantages?

I was wondering about one thing that jumped into my mind yesterday.
I apologize in advance for the misleading title, but I really don't know how to entitle this.
Well, suppose we are two objects ObjA and ObjB, and that, for instance, ObjB has a method that takes an ObjA object as argument.
We can do this (taking java as language):
ObjA instanceA = new ObjA();
ObjB instanceB = new ObjB();
instanceB.method(instanceA);
or
new ObjB().method(new ObjA());
Assume this is the body of some function, so the objects will be destroyed when going out of scope.
My question is:
do we get a performance advantage by not instantiating the singular objects and calling the implicitly as for the second code? Is this readability sacrifice worth something? Or is it all for nothing since the implicitly created objects will be stored in memory and die by scope anyway?
Note: I don't know if I'm saying right with "implicit" or "anonymous", but I have not found much on Google.
Absolutely no difference performance wise.
But in few cases, you will be forced to use first type.
For ex :
ObjA instanceA = new ObjA();
// Do something with instanceA
instanceB.method(instanceA);
If you have nothing to do in middle, I can just use the second way to save a line of code.
In this case readability is the only advantage one way or another.
There's no significant performance or memory benefit.If you store a reference in a local variable and then invoke the method,there may be an extremely small performance penalty for storing the reference.
The anonymous object is created and dies instantaneously. But, still with anonymous objects work can be extracted before it dies like calling a method using the anonymous object:
new ObjB().method(new ObjA());
We can’t use twice or more as the anonymous object dies immediately after doing its assigned task.
The first approach using named variable is required if you need to store the object to use it several times without creating new objects or to store the current result of some method returning an object if there is a risk (e.g. because of multi-threading) the result will be different the very next time. In other cases it's more convenient to use anonymous objects since their scope is the same and there is no namespace cluttering with unneeded identifiers.

How to invoke method of an object whose reference id is stored in String? [duplicate]

My question is relate to security level of JVM
How we can we get the object from memory by proving hash code?
Today i was thinking. I create an object of class A in an execution environment One. And get the hash code from here of that object.
Now in another execution environment i want to get back class A object by providing hash code.
I think it is possible. Because when I execute environment one. Again and again i get that JVM return the same hash code.
Means it first find the object in its cache. If it get the reference, it just return it.
So now back to question, we have to understand what data is copied when we
write =.
Object a=new Object();// here as we know reference of new object will be stored in refvar a.
Then what in actual is passes through.
If we get what data is passed by =(equal operator). We will able to get the object from memory.
Thanks
How we can we get the object from memory by proving hash code?
You can't without access to the internals of the JVM. Even then you would need to scan every object in memory. You would also have the problem than multiple objects with the same hashCode. BTW: By default objects don't have a hashCode until you ask for one.
I think it is possible. Because when I execute environment one. Again and again i get that JVM return the same hash code.
This only works because you are recreating the exact conditions where the hashCode as generated, the slightest changes and you would get different hashCodes.
Means it first find the object in its cache. If it get the reference, it just return it.
By it you mean a cache you would need to maintain, no such cache exists in the JVM.
So now back to question, we have to understand what data is copied when we write =.
Object a=new Object();// here as we know reference of new object will be stored in refvar a.
Then what in actual is passes through.
The reference is passed, like you said. Nothing else.
I guess it is irrelevant since hash code may or may not be related to memory address
take a look documentation
in general each JVM has its own memory stack so whether you can access object from other JVM is depending on JVM implementation and I guess it is rarely possible.

Is chaining method calls to constructors a good practice in Java?

I have always thought that I have to initialize a class, before I can call it's non-static method, however, I came across a solution which had a method like this in it:
public String someStringMethod(){
return new MyClass().toString();
}
So I may be new in development, but is it a good practice? Is this a better way to call a method than the "classic" (see below) way?
public String classicStringMethod(){
MyClass cl = new MyClass();
return cl.toString();
}
Do they have any performance difference? Does the first way has a "special name"?
No significant difference
As the comments explained, both approaches are semantically the same; both ways achieve the exact same result and the choice is really just a stylistic difference.
The second approach assigns the new object to a reference variable. The first approach skips the use of a reference variable. But in both cases the class was used as a definition for instantiating an object, and then the toString method was called on that object.
Semantically, first (chained/fluent) syntax usually informs you that the created object will be used only for a single chain of operations, and discarded afterwards. Since there's no explicit reference exported, it also signals that the scope of life of the object is limited to that very statement. The second (explicit) one hints that the object is/was/will be used for additional operations, be it another method calls, setting a field to it, returning it, or even just debugging. Still, the general notion of using (or not) temporary helper variables is just a stylistic one.
Keep in mind that the variable is not the object. For example, the line Dog hershey = new Dog( "Australian Shepard" , "red", "Hershey" ); uses two chunks of memory. In one chunk is the new object, holding the state data for the breed and color and name. In the other separate chunk is the reference variable hershey holding a pointer to the memory location of the memory chunk of the Dog object. The reference variable lets us later refer to the object.
Java syntax makes this jump from reference variable to object so seamlessly that we usually think of hershey as the Dog object “Hershey”, but in fact they are separate and distinct.
As for performance, any difference would be insignificant. Indeed, the compiler or JVM may well collapse the second approach’s two lines into the first approach‘s single line. I don't know for sure, and I don't really care. Neither should you. Our job is to write clear readable code. The job of the compiler and JVM is to run that code reliably, efficiently, and fast. Attempting micro-optimizations has been shown many times to be futile (or even counter-productive) as the JVM implementations are extremely sophisticated pieces of software engineering, highly-tuned for making such optimizations. You can best assist the compilers and JVMs by writing simple straight-forward code without “cleverness”.
Note that the second approach can make debugging easier, because your debugger can inspect the instantiated object by accessing the object via the reference variable, and because you can set a line breakpoint on that particular constructor call explicitly.

Java List/Array List clarification

If someone can explain the difference between these two type of Array Initializations that would be great:
There is a static method getList() in class ListReturn, which returns an ArrayList<Some_Custom_Object> upon calling.
In the invoking class, I can call the function in two ways as follows:
List<Some_Custom_Object> listFromCall = new ArrayList<Some_Custom_Object>();
listFromCall=ListReturn.getList();//works completely fine
List<Some_Custom_Object> listFromCall = ListReturn.getList();//Works completely fine
My question here is, in the second scenario, don't we have to initialize or instantiate the listFromCall object?, can we directly assign return values from method to un-initialized List/ArrayList object?
Can someone please explain what is going on beneath the hood here?.
Thanks
You only have to initialize a variable if you read from it before you write to it.
If you write to an uninitialized variable, the computer doesn't care because you're initializing it with the return value from ListReturn.getList().
In fact, you shouldn't needlessly initialize object variables to anything but null if they're going to be overwritten before use. Otherwise, you create and garbage collect an extra object for no reason.
Let's discuss both way one by one,
First Way :
List<Some_Custom_Object> listFromCall = new ArrayList<Some_Custom_Object>();
means, something likewise,
listFromCall=ListReturn.getList();//works completely fine
it will reflect on listFromCall's value assignment, see below image for
deeper understanding,
Here, completion of both statement, total either 2-object created(1
will eligible for garbage collection after second created and assign)
or 1-object created (which will become eligible for garbage collection
and assign null to reference variable)
Your Second Way :
Now if you do something likewise,
2. List<Some_Custom_Object> listFromCall = ListReturn.getList();//Works completely fine
Then it will appear something likewise,
So, here either 1-object(of ArrayList) will created on heap or not.

In java, how can we destruct an instance of a class from a method within the class

I approached it similar to the case of deleting any usual object, ie, simply making the reference null and letting the Garbage Collector do its job.
However for equating to null within a class, the only reference to the object is "this". So is the code for the following class valid:
class A{
public A(){
//Init
}
public void method destruct(){
if(someCondition){
this=null; //Is this statement valid? Why / Why not?
}
}
}
You don't "destruct" objects in Java. This is wrong-headed. Don't do it.
Objects are created on the heap in Java. They live as long as there's a reference that points to them. The garbage collector cleans up the mess.
You should certainly do what you can to make sure that you don't accumulate and hold onto references unnecessarily (e.g. Listeners in Swing).
But your proposal is not the right thing at all. Cease and desist.
this=null; //Is this statement valid? Why / Why not?
It is not valid Java because this is not an lvalue; i.e. not something you can assign to. This is a compilation error, just like 42 = i; is a compilation error.
(The JLS says the following about assignments: "The result of the first operand of an assignment operator must be a variable, or a compile-time error occurs." - JLS 15.26.1 The JLS text then goes on to list the different things that qualify as variables, and this is not one of them.)
Besides, as duffymo says, it is a totally wrong-headed thing to do in Java. Just let the GC do its job.
NOTE: What you suggest is highly unlikely to be useful.
What you can do is use delegation.
class A {
private AImpl impl = new AImpl();
public void close() {
if (impl != null)
impl.close();
impl = null;
}
}
As all references are indirect, you can ensure there is only one reference to the real object and clear it.
Proxies in some OSGi containers do this when a component is unloaded. As the container has little control over the lifecycle of the references, it would make it difficult to ever unload a library (the implementation).
Your goal is deeply misguided.
Either someone outside the instance holds a non-weak reference to it. Then it will not be collected no matter what you do inside. Or no one does, then it will eventually be collected, no matter what you do inside. In either case, this=null would make no difference, even it were legal java code. Don't do it. If you are concerned about object lifetime and memory exhaustion, look out side the object that you want to get rid of.
Setting this = null is like trying to say that an object doesn't reference itself. It always implicitly references itself. You need to find what other objects might be referencing this one and clear their references instead. Usually, this happens automatically because most objects are retained through local variables that are on the stack. When I say "retained" I mean that they are referenced through a chain of references that ultimately leads to a variable on the stack. When you leave the method, the reference is cleared. But if you have a static variable referencing this object that might be a case where you must explicitly set it null.
For the java garbage collector to pick up your class it should not be referenced be OTHER classes.
The statement this=null; is illegal because the left hand side of an assignment must be a variable.
There is no way to explicitly delete the particular reference in Java. Java does this to avoid hanging references. If you delete an object then other objects refer to it can potentially try to access the data and get a reference to invalid data.
You shouldn't be trying to delete objects anyways, just move all references to the object to null.
No. An instance object could be deleted by the GC when no reference points to it, that its, from all running threads could not navigate till the object. When you are in the object executing a method, this method is invoked from outside, so there is a reference to the object. The object itself can not be destroyed, as a reference to it still remains outside.
Consider another approach for memory management.
In methods this is reference to object on which current method is invoked so it should not be possible to changed it. Think of this as final reference.
Life cycle of objects are ruled by the JVM, due this reason an object cannot decide when itself is no longer needed. What you could do is put some effort on the references to this object. Type of references could be used in order to point the "importance" of the object.
The basic types of references in java can be found here:
More here: http://docs.oracle.com/javase/1.3/docs/api/java/lang/ref/package-summary.html
Discussion about the references here:
What is the difference between a soft reference and a weak reference in Java?
and
Understanding Java's Reference classes: SoftReference, WeakReference, and PhantomReference
You can call :
System.gc() or RuntimeUtil.gc() from the jlibs
but if you do that you mess with the JVM runtime.
If you set refernce to null, the object still exists , its just its' reference won't refer to this object and at the next time GC will be invoked it will destroy the object(unless other references refer to it).
No the above code is not valid. The reference this of a class only lasts as long as the JVM is being executed. Setting this == null will infact give you a compiler error because though this is termed as reference it is actually a value and you can't assign anything to a value.
Also it is unnecessary since this is valid for only as long as the execution is in that code and GC cannot claim an object which is still executing. However as soon as the execution ends for the object, this will also be lost and the object will automatically become available for GC (i.e. if no other reference to the object exists)
This is a compilation error. You cannot assign NULL to 'this'. Keyword 'this' can be used on the right side of equals (with the exception that left hand is not NULL. Reason: nothing can be assigned to null).
For destruction,in java, you have a GC who can do this job for you behind the scenes.
Please note that for user defined objects you can still do something like -
object reference = null;
However 'this' cannot be used on left side of equals.
The very reason why the execution thread is inside the destruct() method tells me that there is a caller that is holding a reference to this instance of class A. So, nevertheless, you cant do anything like "this = null" in java - it would not have helped, even though it was allowed in java. You cant destruct to objects in java.

Categories

Resources