I sometimes see the code of this kind in some library APIs and just in someone's code:
class SomeClass {
private WeakReference<SomeObject> objectWeakReference; // initialized elsewhere
public boolean isObjectAttached() {
return objectWeakReference.get() != null;
}
public SomeObject getObject() {
return objectWeakReference.get();
}
}
and
public void checkAndGetWeakReference() {
SomeClass someClass = new SomeClass();
if (someClass.isObjectAttached()) {
someClass.getObject().doSomethingDirectlyOnReturnedObject(); // can the returned reference be null here ?
}
}
And I'm always worried if there could be NullPointerException once in a blue moon, assuming there are no strong reference to the underlying object at this point.
I don't really know when exactly Garbage Collector can start deleting objects from memory and how does it correlate with the basic thread flow.
It would be nice if someone can shed the light on this particular subject and/or provide some information about the topic.
P.S. I would personally get reference only once and assign it to strong reference. The point of the question is to get some proof the code above is wrong.
The whole point of the WeakReference (and SoftReference as well) is that the referred object may be gc'd at any time no strong reference to the object exists.
Since there exists no strong reference when isObjectAttached() returns, yes it can be garbage collected before it actually gets to execute getObject(). The whole idom is faulty for this use case.
The only safe way is to first get the reference (e.g. to a local variable) and then check it against null. The object can then not be garbage collected in that case, because a local variable is a strong reference.
As per java doc. You should not rely on Garbage collector. Its not sure when it will be executed. Though you are trying explicitly System.gc()
Its always been a lowest priority for JVM for garbage collector. When JVM is free or when your program is around to ran out of memory it can execute GC.
In other case when your program will exit. It will be garbage collected before it is flushed out of JVM memory.
Please refer javadoc for detailed explanation for GC.
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
I would like to add something to all answers.
Your object can be null when you call below method :
public SomeObject getObject() {
return objectWeakReference.get();
}
about garbage collection of this object.
If you do something like below :
public static void main(String args[]) {
SomeClass oSomeClass = new SomeClass();
// this one is strong reference "obj"
// this object can be null. Best practice is to null check before you use it.
// Or i will suggest to call isObjectAttached() method before you use it
Object obj = oSomeClass.getObject();
}
When you do obj = null; somewhere in code after above statement.
This object memory is available for garbage collection. Whenever JVM feels to clean memory. Yes it can collect this object.
Regarding proof of code you are asking.
public boolean isObjectAttached() {
return objectWeakReference.get() != null;
}
This method is made for you to check whether this object is present in memory or it has a valid reference for you.
If it returns true you will never get nullpointer exception.
but if you are not using this method i will suggest to use null check always before you use your object.
Hope I am on right direction and making some sense in my answer. Please respond accordingly.
We all are here to learn ;-)
Enjoy Java, OOP concepts.
Garbage collector internally has its heuristics to collect soft/weak/phantom references. It will not collect those objects in subsequent GC calls. It tracks these objects until it reaches the threshold of that heuristics, GC is not allowed to collect these references.
Related
I'm confused with this program:
class Point {
private final int x;
private final int y;
}
public class App
{
WeakReference<Point> newPoint() {
Point referent = new Point();
return new WeakReference<Point>(referent); // after return, stack parameter referent is invalid.
}
public static void main( String[] args ) {
App a = new App();
WeakReference<Point> wp = a.newPoint(); // wp is hold valid or invalid reference?
System.out.println(wp.get()); // not null
}
}
I knew that if weak reference is pointing to an object that's no longer alive, its get() should return null. But in my code, seems its still alive.
Where did I get wrong?
I knew that if weak reference is pointing to an object that's no longer alive, its get() should return null. But in my code, seems its still alive.
Your understanding is imprecise, especially where it relies on the idea of aliveness. Reference objects in general and WeakReference objects in particular are not directly concerned with any of the senses of aliveness that I recognize. Rather, they are concerned with reachability.
The API docs for java.lang.Reference#get() (which is not overridden by WeakReference) say this:
Returns this reference object's referent. If this reference object has been cleared, either by the program or by the garbage collector, then this method returns null.
Note well that the condition for get() returning null is rather specific: the reference object has been cleared. This is achieved for a given instance by invoking that instance's clear() method. As the doc indicates, this may be done by the garbage collector or by the application.
Among the key differences between Reference subclasses is the conditions under which the garbage collector will perform such clearing. For WeakReferences, the API docs say:
Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object [...].
Thus, until the garbage collector determines that a given object is (only) weakly reachable, it will not clear weak references to that object. The garbage collector probably does not run at all during the brief run of your small program, and if it did run, it would be surprising for it to be timed correctly to observe the Point in question to be weakly reachable before the reference's get() method is invoked.
You could try forcing a GC run by invoking System.gc() at the appropriate place. I anticipate that doing so will result in the weak reference being cleared. That would be for demonstrative purposes only, however. Generally speaking, you should rely on Java to perform GC when appropriate, not force it.
You have one big object in java. it has got 4 or five references. you don't know all those references. At time on deletion you know only one reference and you want to delete that object completely. How to achieve that? and also if you want to know other references then to what is the best way to do that.
It is not in our hand.. You can just nullify it from your end..
Object a = new Object();
a = null; // after that, if there is no live thread which is accessing members,it will be deleted by garbage collector
You could try Finalize() or System.runFinalization() but frankly, if there are references still pointing to the object, then I think the GC will ignore your request.
It is not possible in Java.
If you have strong reference referring your object, you cannot force JVM to GC that object. It simply cannot guarantee the program will work.
If codes of all other references are in your control, consider changing them to use WeakReference or SoftReference
There are some things that are not in our hands and its better to leave it to the JRE to handle it. All we can do that we make sure that the we make them null explicitly after using them.
{
// Some block
HugeObject obj = HugeObject.getInstance();
// Use it
obj = null;
}
// end of block
Java memory handling is just built to prevent that. An object is guaranteed to live as long as a reference to this object exists. As far as I know there is no (official) way to get to know the other references to an object (and there should be no need for that).
In Java GC(Garbage collector) handles heap cleanup. If an Object has no live references to it then it will automatically be cleaned up. So you need to make sure there are no live references to the Object.
Making it null is one of the way. But it will not guarantee it's cleanup if there is some other Object pointing to the same reference. That is why writing good code involves closing all the resources after use which includes making it to null.
If you are running low on heap you can try increasing heap size or calling System.gc() but again calling gc manually does not guarantee gc will actually be performed. it depends on lot of parameters which are JVM dependent.
What kind of references are these to the object? Are these references created by you and at runtime you don't keep track of of those references. If this is the case, you can wrap your references to the object in soft/ weak reference and then explicitly run the GC request. Otherwise, on runtime, if any live thread has access to the object. GC shall not delete that object.
It is hard to answer no knowing your use case, but if there is one location that you want to be able to remove it from then you can store every other reference to it as a WeakReference. Java normally uses strong refrences when referencing objects and the GC will only clear something when it has no more strong references. However, if you use WeakRefrences and your strong refrence ever goes out of scope there is no guarantee that your data will remain even if it is still needed.
I could be mistaken about this though, as I haven't used this class in a year or two.
On WeakReferences:
http://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html
You can declare your objects as WeakReference and add them in ReferenceQueue. In this way , whenever your object will not be further referenced , it will be liable for GC.
/**
Initialize the reference queue , even if you don't do it , no problem . Default reference queue will be taken.
**/
ReferenceQueue<? super Object> testReferenceQueue = new ReferenceQueue<Object>();
Map<String,String> demoHashMap = new HashMap<String,String>();
demoHashMap.put("SomeValue","testValue");
// Declare the object as weak object and put it in reference queue
WeakReference<?> weakObject = new WeakReference<Object>(demoHashMap,testReferenceQueue );
demoHashMap.clear();
demoHashMap = null; // This object is not referenced from anywhere
if(weakObject!=null){
System.out.println("Object is not GCd yet");
}else{
System.out.println("It is already garbage collected");
}
Can someone explain the difference between the three Reference classes (or post a link to a nice explanation)? SoftReference > WeakReference > PhantomReference, but when would I use each one? Why is there a WeakHashMap but no SoftHashMap or PhantomHashMap?
And if I use the following code...
WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) { // ref can get collected at any time...
System.gc(); // Let's assume ref gets collected here.
System.out.println(ref.get()); // Now what?!
}
...what happens? Do I have to check if ref is null before every statement (this is wrong, but what should I do)? Sorry for the rapid-fire questions, but I'm having trouble understanding these Reference classes... Thanks!
The Java library documentation for the java.lang.ref package characterizes the decreasing strength of the three explicit reference types.
You use a SoftReference when you want the referenced object to stay alive until the host process is running low on memory. The object will not be eligible for collection until the collector needs to free memory. Loosely stated, binding a SoftReference means, "Pin the object until you can't anymore."
By contrast, use a WeakReference when you don't want to influence the referenced object's lifetime; you merely want to make a separate assertion about the referenced object, so long as it remains alive. The object's eligibility for collection is not influenced by the presence of bound WeakReferences. Something like an external mapping from object instance to related property, where the property need only be recorded so long as the related object is alive, is a good use for WeakReferences and WeakHashMap.
The last one—PhantomReference—is harder to characterize. Like WeakReference, such a bound PhantomReference exerts no influence on the referenced object's lifetime. But unlike the other reference types, one can't even dereference a PhantomReference. In a sense, it doesn't point to the thing it points to, as far as callers can tell. It merely allows one to associate some related data with the referenced object—data that can later be inspected and acted upon when the PhantomReference gets queued in its related ReferenceQueue. Normally one derives a type from PhantomReference and includes some additional data in that derived type. Unfortunately, there's some downcasting involved to make use of such a derived type.
In your example code, it's not the ref reference (or, if you prefer, "variable") that can be null. Rather, it's the value obtained by calling Reference#get() that may be null. If it is found to be null, you're too late; the referenced object is already on its way to being collected:
final String val = ref.get();
if (null != val)
{
// "val" is now pinned strongly.
}
else
{
// "val" is already ready to be collected.
}
A link: https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references
PhantomHashMap wouldn't work very well as get always returns null for phantom references.
Caches are difficult, so SoftHashMap might not work as well as you might think. However, I believe Google's collection library contains a general reference map implementation.
You should always check that get returns non-null. (Note, that not checking that the Reference reference itself is not-null.) In the case of interned strings it always will, but (as ever) don't try to be "clever" about it.
It should also be mentioned, as stated on the comment by Truong Xuan Tinh, here: http://blog.yohanliyanage.com/2010/10/ktjs-3-soft-weak-phantom-references/
That JRockit JVM implements weak/soft/phantom references differently than Sun JVM.
String str = new String("hello, world");
WeakReference<String> ref = new WeakReference<String>(str);
str = null;
if (ref != null) {
System.gc();
System.out.println(ref.get());
}
In this case, it will output null. The call to System.gc() is important here.
How to prevent an object from getting garbage collected?
Are there any approaches by finalize or phantom reference or any other approaches?
I was asked this question in an interview. The interviewer suggested that finalize() can be used.
Hold a reference. If your object is getting collected prematurely, it is a symptom that you have a bug in the design of your application.
The garbage collector collects only objects to which there is no reference in your application. If there is no object that would naturally reference the collected object, ask yourself why it should be kept alive.
One usecase in which you typically have no references, but want to keep an object is a singleton. In this case, you could use a static variable. One possible implementation of a singleton would look like this:
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqInstance;
}
}
Edit: Technically, you can store a reference somewhere in your finalizer. This will prevent the object from being collected until the collector determines again that there are no more references. The finalizer will only be called at most once, however, so you must ensure that your object (including its superclasses) need not be finalized after the first collection. I would advise you, however, not to use this technique in actual programs. (It will leave colleagues like me yelling WTF!? ;)
protected void finalize() throws Throwable {
MyObjectStore.getInstance().store(this);
super.finalize(); // questionable, but you should ensure calling it somewhere.
}
The trick answer your interviewer was looking for is probably that he wants you to know that you can prevent garbage collection from removing an object by forcing a memory leak.
Obviously, if you keep a reference to the object in some long-lived context, it won't be collected, but that's not what the OP's recruiter asked about. That's not something which happens in the finalize method.
What you can do to prevent garbage collection from within the finalize method is to write an infinite loop, in which you call Thread.yield();(presumably to keep an empty loop from being optimized away):
#Override
protected void finalize() throws Throwable {
while (true) {
Thread.yield();
}
}
My reference here is an article by Elliot Back, in which describes forcing a memory leak by this method.
Just another way in which finalize methods are evil.
The best way is to use Unsafe, although ByteBuffer might be a possible workaround for some cases.
Also search for the keyword "off-heap" memory.
Unsafe
Advantages over ByteBuffer:
allows objects to be represented directly, without for serialization and thus faster
no bounds checking, so faster
explicit deallocation control
can allocate more than the JVM limit
It is not however easy to get working. The method is described in the following articles:
http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/
https://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/
http://java.dzone.com/articles/understanding-sunmiscunsafe
They all consist of the following steps:
we need a sizeof operator, which Unsafe does not have. How to make one was asked at: In Java, what is the best way to determine the size of an object?. The best options is likely the instrument API, but that requires you to create a Jar and use special command line options...
once we have sizeof, allocate enough memory with Unsafe#allocateMemory, which is basically a malloc and returns an address
create a regular on heap object, copy it to the allocated memory with Unsafe#copyMemory. To do this, you need to the address of the on-heap object, and the size of the object
set an Object to point to the allocated memory, then cast the Object to your class.
It does not seem possible to set the address of a variable directly with Unsafe, so we need to wrap the object into an array or wrapper object, and use Unsafe#arrayBaseOffset or Unsafe#objectFieldOffset.
once you are done, free the allocated memory with freeMemory
If I ever get this to not segfault I will post an example :-)
ByteBuffer
Advantages over Unsafe:
stable across Java versions while Unsafe may break
does bound checking, so safer than... Unsafe, which allows for memory leaks and SIGSEGV
JLS says:
The contents of direct buffers may reside outside of the normal garbage-collected heap.
Example of usage with primitives:
ByteBuffer bb = ByteBuffer.allocateDirect(8);
bb.putInt(0, 1);
bb.putInt(4, 2);
assert bb.getInt(0) == 1;
assert bb.getInt(4) == 2;
// Bound chekcs are done.
boolean fail = false;
try {
bb.getInt(8);
} catch(IndexOutOfBoundsException e) {
fail = true;
}
assert fail;
Related threads:
Difference between "on-heap" and "off-heap"
If there is still a reference to the object, it won't get garbage collected. If there aren't any references to it, you shouldn't care.
In other words - the garbage collector only collects garbage. Let it do its job.
I suspect what you might be referring to is if your finalize method stashes away a reference to the object being finalized. In this case (if my reading of the Java Language Spec is correct) the finalize method will never be re-run, but the object will not yet be garbage collected.
This is not the sort of thing one does in real life, except possibly by accident!
This sounds like one of those interview-only-time-you'll-see-it questions. finalize() is run when your object is getting garbage collected, so it'd be pretty perverse to put something in there to prevent collection. Normally you just hold a reference and that's all you need.
I'm not even sure what would happen if you'd create a new reference for something in the finalizer - since the garbage collector's already decided to collect it would you then end up with a null ref? Seems like a poor idea, in any case. e.g.
public class Foo {
static Foo reference;
...
finalize (){
reference = this;
}
}
I doubt this would work, or it might work but be dependant on the GC implenetation, or be "unspecified behavior". Looks evil, though.
The key point is if we set the real reference variable pointing to the object null,although we have instance variables of that class pointing to that object not set to null.
The object is automatically eligible for garbage collection.if save the object to GC, use this code...
public class GcTest {
public int id;
public String name;
private static GcTest gcTest=null;
#Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("In finalize method.");
System.out.println("In finalize :ID :"+this.id);
System.out.println("In finalize :ID :"+this.name);
gcTest=this;
}
public static void main(String[] args) {
GcTest myGcTest=new GcTest();
myGcTest.id=1001;
myGcTest.name="Praveen";
myGcTest=null;
// requesting Garbage Collector to execute.
// internally GC uses Mark and Sweep algorithm to clear heap memory.
// gc() is a native method in RunTime class.
System.gc(); // or Runtime.getRuntime().gc();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\n------- After called GC () ---------\n");
System.out.println("Id :"+gcTest.id);
System.out.println("Name :"+gcTest.name);
}
}
Output :
In finalize method.
In finalize :ID :1001
In finalize :ID :Praveen
------- After called GC () --------
Id :1001
Name :Praveen
I wonder if what they're going for is the pattern with resource pools (e.g. for network/db connections, or threads) where you use finalize to return a resource to the pool so that the actual object holding the resource isn't GC'ed.
Stupid example, in Java-like pseudocode and missing any kind of synchronization:
class SlowResourceInternal {
private final SlowResourcePool parent;
<some instance data>
returnToPool() {
parent.add(this);
}
}
class SlowResourceHolder {
private final SlowResourceInternal impl;
<delegate actual stuff to the internal object>
finalize() {
if (impl != null) impl.returnToPool();
}
}
I believe there is a pattern out there for this. Not sure if it the factory pattern. But you have one object that creates all your objects and holds a reference to them. When you are finished with them, you de-reference them in the factory, making the call explicit.
We have three ways to achieve same -
1) Increasing the Heap -Eden space size .
2) Create Singleton class with Static reference .
3) Override finalize() method and never let that object dereference.
There are 3 ways to prevent an Object from Garbage Collection as following:-
Increase the Heap Size of JVM
// Xms specifies initial memory to be allocated
// and Xmx specifies maximum memory can be allocated
java -Xms1024m -Xmx4096m ClassFile
Use a SingleTon Class Object as #Tobias mentioned
public class MySingletonClass {
private static MySingletonClass uniqueInstance;
// marking constructor as private
private MySingletonClass() {
}
public static synchronized MySingletonClass getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqInstance;
}
}
We can override finalize method. That is last method executed on an object. Hence, it will remain in memory.
// using finalize method
class MyClassNotGc{
static MyClassNotGc staticSelfObj;
pubic void finalize() {
// Putting the reference id
//Object reference saved.
//The object won't be collected by the garbage collector
staticSelfObj = this;
}
}
In what situations in java is explicit nulling useful. Does it in any way assist the garbage collector by making objects unreachable or something? Is it considered to be a good practice?
In Java it can help if you've got a very long-running method, and the only reference to the an object is via a local variable. Setting that local variable to null when you don't need it any more (but when the method is going to continue to run for a long time) can help the GC. (In C# this is very rarely useful as the GC takes "last possible use" into account. That optimization may make it to Java some time - I don't know.)
Likewise if you've got a member field referring to an object and you no longer need it, you could potentially aid GC by setting the field to null.
In my experience, however, it's rarely actually useful to do either of these things, and it makes the code messier. Very few methods really run for a long time, and setting a variable to null really has nothing to do with what you want the method to achieve. It's not good practice to do it when you don't need to, and if you do need to you should see whether refactoring could improve your design in the first place. (It's possible that your method or type is doing too much.)
Note that setting the variable to null is entirely passive - it doesn't inform the garbage collector that the object can be collected, it just avoids the garbage collector seeing that reference as a reason to keep the object alive next time it (the GC) runs.
In general it isn't needed (of course that can depend on the VM implementation). However if you have something like this:
private static final Map<String, String> foo;
and then have items in the map that you no longer need they will not be eligible for garbage collection so you would need to explicitly remove them. There are many cases like this (event listeners is another area that this can happen with).
But doing something like this:
void foo()
{
Object o;
// use o
o = null; // don't bother doing this, it isn't going to help
}
Edit (forgot to mention this):
If you work at it, you should find that 90-95% of the variables you declare can be made final. A final variable cannot change what it points at (or what its value is for primitives). In most cases where a variable is final it would be a mistake (bug) for it to receive a different value while the method is executing.
If you want to be able to set the variable to null after use it cannot be final, which means that you have a greater chance to create bugs in the code.
One special case I found it useful is when you have a very large object, and want to replace it with another large object. For example, look at the following code:
BigObject bigObject = new BigObject();
// ...
bigObject = new BigObject(); // line 3
If an instance of BigObject is so large that you can have only one such instance in the heap, line 3 will fail with OutOfMemoryError, because the 1st instance cannot be freed until the assignment instruction in line 3 completes, which is obviously after the 2nd instance is ready.
Now, if you set bigObject to null right before line 3:
bigObject = null;
bigObject = new BigObject(); // line 3
the 1st instance can be freed when JVM runs out of heap during the construction of the 2nd instance.
From "Effective Java" : use it to eliminate obsolete object references. Otherwise it can lead to memory leaks which can be very hard to debug.
public Object pop(){
if(size == 0)
throw new EmptyStatckException();
Object result = elements[--size];
elements[size] = null; //Eliminate Object reference
return result;
}
If you are nulling an object that is about to go out of scope anyway when your method block closes, then there is no benefit whatsoever in terms of garbage collection. It is not unusual to encounter people who don't understand this who work really hard to set a lot of things to null needlessly.
Explicit nulling can help with GC in some rare situations where all of the following are true:
The variable is the only (non-weak) reference to the object
You can guarantee that the object will no longer be needed
The variable will stay in scope for an extended period of time (e.g. it is a field in a long-lived object instance)
The compiler is unable to prove that the object is no longer used, but you are able to guarantee this though your superior logical analysis of the code :-)
In practice this is quite rare in good code: if the object is no longer needed, you should normally be declaring it in a narrower scope anyway. For example, if you only need the object during a single invocation of a method, it should be a local variable, not a field in the enclosing object.
One situation where explicit nulling is genuinely useful: if null is used to indicate a specific state then setting to a null value is sometimes going to be necessary and useful. Null is a useful value in itself for a couple of reasons:
Null checks are extremely fast, so conditional code that checks for null is typically more efficient than many alternatives (e.g. calling object.equals())
You get an immediate NullPointerException if you try to dereference it. This is useful because it is good Fail Fast coding style that will help you to catch logic errors.
See also WeakReference in J2SE.