Removing objects from Java Collections - java

I have a HashMap (although I guess this question applies to other collections) of objects. From what I understand, when the documentation talks about removing mappings, then it is removing the entry from the hashtable, i.e. not necessarily destroying the actual object. If the only remaining reference to the object is in this table, then will the object get garbage collected?
If I do map.clear() and those objects that were in the table are not referenced anywhere else, will they get garbage collected?
What is the fastest way, to actually remove all entries from the table, but also destroy those objects.

Yes, if the collection is the last place these objects are referenced they are eligible for garbage collection after they have been removed from the collection. And no, you can not destroy these objects forcefully. The garbage collector will handle them when it feels like it.

If the only remaining reference to the object is in this table, then will the object get garbage collected?
If there are no other references to an object, then the object will be garbage collected sometime in the future.
You should not have to force destruction of the objects. If they are extremely heavyweight objects (or you have too many objects to fit in memory), this points to a more fundamental problem with your code.
If you really must, then you can call System.gc(), although this is not good practice, and will always be a bellwether of underlying problems in your code.

Generally speaking, you have no strong control over when an object is specifically destroyed. Any object is eligible for garbage collection when there are no more (strong) reference to it - but there are no guarantees about when it will be garbage collected or in fact if it ever will be. Even calling System.gc() or Runtime.gc() provides no guarantees about actually doing anything, it's merely a hint to the JVM that it might want to consider garbage collecting now. I believe the only guarantee you get is that if an OutOfMemoryError is thrown, all potential garbage collections were done before the error was thrown.
There are implications here for handling sensitive information such as passwords. Since Strings cannot be programatically cleared, you ideally don't want to store the password as such. If you instead store it as an array of characters, you can then use Arrays.fill(' ') to overwrite the password and guarantee it is no longer resident in memory from that point.
Back back on topic - you are right that both operations will make the object eligible for garbage collection if it is not being referenced elsewhere. Collection.clear() is indeed the fastest way to drop references to all the objects in a collection at once.

Note that WeakHashMap allows you to place objects in it and have them eligible for garbage collection as soon as there are no more references to the key (not the value) outside the map - the map entry will disappear at this point.
In general you should not worry about when objects are garbage collected - the JVM decides this, and it knows a lot more about its memory needs and possible delays than you. What you should worry about is to make sure that objects you don't need anymore are eligible for garbage collection.

To have something truly garbage collected there can be no Strong references to the object. Objects with weakReference's may be garbage collected. Use WeakHashMap to make sure they are garbage collected, as that in a HashMap there is still references to the object.

You can initiate a call to System.gc() after you clearyour map, but it's generally not a good idea.

Related

Do I need to keep a strong reference to a WeakReference that is only used to perform finalization?

I'd like to use a WeakReference as a more efficient finalize() method, for the purpose of freeing native resources associated with an object as soon as it becomes possible to do so, without using finalization (which has significantly higher costs than using a WeakReference).
Since this is the only purpose of the WeakReference (I will never use the WeakReference to obtain the referenced object), it seems wasteful to take the time and space to maintain a list of my WeakReferences to prevent them from being garbage collected.
But if a normal object is constructed and no strong reference is kept to it, it will simply be freed by the garbage collector, and I can't find anything in the Javadoc that suggests this is different for a WeakReference.
Is it necessary to keep a reference to a WeakReference to prevent it from being garbage collected, or, if it's to be enqueued in a ReferenceQueue, will that keep it alive until it's been collected from the queue?
Is it necessary to keep a reference to a WeakReference to prevent it from being garbage collected
Have a look at the java.lang.ref package description, it dedicates a whole paragraph to answering your question:
The relationship between a registered reference object and its queue is one-sided. That is, a queue does not keep track of the references that are registered with it. If a registered reference becomes unreachable itself, then it will never be enqueued. It is the responsibility of the program using reference objects to ensure that the objects remain reachable for as long as the program is interested in their referents.

WeakHashMap Randomly clears

I am running a game, when I start up I load images into a WeakHashMap of Images. When I run my game, my RAM just keeps going up, then eventually my WeakHashMap just unload all of their data. Is this relates to Garbage Collection? Any solutions?
You can create a HashMap using SoftReferences instead of WeakReferences - the garbage collector will be a bit less eager about GCing it. Just copy the WeakHashMap source code, replacing the WeakReferences with SoftReferences.
As Louis Wasserman suggested this is expected behaviour. I think you may want a normal hashmap. Please read the docs regarding WeakHashMap at http://docs.oracle.com/javase/6/docs/api/java/util/WeakHashMap.html
A java.util.WeakHashMap is a type of map that, as its description might suggest, keeps only weak references to its keys. Weak references, as you know, are references that do not prevent the garbage collector from collecting the referenced objects. In order to prevent an object from being garbage collected, you must maintain a strong reference to the object somewhere.
If you want the data to be protected from garbage collection, store it in a regular HashMap. For your particular application, you may want to write your own map implementation that keeps soft references (references that the gc only clears if it has to, rather than always clearing) to the images, and have it automatically load missing art when that art is called for. (Could be tricky if you need it to be all thread safe, though...)

How to keep alive Java objects?

I'm just thinking about a way of keeping away Java objects from garbage collection even if it is not being referred for a reasonable amount of time.
How to do that?
Have a static container in your main class that you put a reference to the objects in. It can be a Map, List, whatever. Then you'll always have a reference to the object, and it won't be reclaimed. (Why you would want to do this is another question...)
Which is to say: As long as a reachable reference to an object exists, it will not be garbage-collected. If your code has a reference and tries to use it, the object will be there. You don't have to do anything special to make that happen (nor should you). (A reachable reference means that the reference is from something that is, itself, reachable from something other than the things it references. Put more simply: The GC understands about circular references and so can clean up A and B even if they refer to each other, as long as nothing else refers to either of them.)
[...] even if it is not being referred for a reasonable amount of time.
If there's any chance what so ever that an object will be accessed in the future, the object will not be garbage collected.
This is due to the fact that if you have a reference to the object, it won't be garbage collected, and if you don't have a reference to the object, there's no way you will be able to access it ever.
In other words, an ordinary reference will never mystically turn into a null just because the garbage collector observed that the object hadn't been accessed for a long time and thought it was time to reclaim it.
You could also create a static instance of the object in its own class. For example if it is a singleton, having a static instance field in the class.
There are mechanisms that will hold a reference to an object, but still allow it to be garbage collected, if there are no other references otherwise.
Look at WeakReference and SoftReference. If you want more details on reachability as far as the jvm is concerned, see:
http://download.oracle.com/javase/6/docs/api/java/lang/ref/package-summary.html#reachability
As far as time is concerned, the garbage collector doesn't know or care about how often an object is used. Either another object has a reference to the target (even if it's not using it), or there are no references to the target. If there are no references to the object, it could never be used again, and will eventually be freed (even if you wanted to, you couldn't obtain a reference to the object again) The longer-living an object is, the longer it takes for the jvm to free it, due to generational garbage collection.
I'm just thinking about a way of keeping away Java objects from garbage collection even if it is not being referred for a reasonable amount of time.
On the face of it, this question doesn't make sense. If an object is not referenced (or more a precisely, if it is not reachable) then the garbage collector will collect it. If you want to prevent an object from being garbage collected then you have to make sure that it is reachable. (Actually, it has to be strongly reachable to guarantee that it won't be GC'ed : see #Austen Holmes answer and the page that he references.)
But actually, I think that you are confusing "refered" / referenced / reachable with accessed or used; i.e. with the act of accessing a field or call a method of the object. If that is what you are asking, then I can assure that the garbage collector neither knows or cares whether your code has recently accessed / used an object.
The reachability criteria is actually about whether your code could access the object at some point in the future, and (therefore) whether the object needs to be kept so that this will work. The reachability rule means that if an object could be accessed, then it will be kept. It makes no difference how long it was since you last accessed it.

Memory Management in Java

How can I delete object manually in Java? Is there any method like obj.delete() or obj.kill()
There is no real way. Java has a special Garbage Collector which does that for you. Once your object doesn't have any references to it, it will be picked up by the Garbage Collector at some point and destroyed.
From Learning Java Tutorials:
The Garbage Collector
An object is eligible for garbage
collection when there are no more
references to that object. References
that are held in a variable are
usually dropped when the variable goes
out of scope. Or, you can explicitly
drop an object reference by setting
the variable to the special value
null. Remember that a program can have
multiple references to the same
object; all references to an object
must be dropped before the object is
eligible for garbage collection.
There is no way to delete an object. Java's Garbage Collector will do it automatically when an object has no more references.
You can however run the Garbage Collector once you have removed all references to an object by calling System.gc(). Please do read the method's documentation carefully. It only guarantees best-effort to delete all objects marked for deletion.
You should also go through these discussions
Java memory management best practices
Java finalize method call
One of the main reasons for Java being so popular is the Garbage Collection. You do not have to worry about allocating or deallocating memory. That being said if you want to get rid of an object just set all references to the object to null and once the garbage collector runs the object will be disposed of.
You do have to worry about closing resources such as files, sockets, database connections etc... and for that you should do it in a try/finally block.
just assign the null value to it.
Let GC take care of this
obj = null;

can any unused object escape from Garbage Collector?

Is there any possibility that a object which is not referenced anywhere and still existing on heap. I mean is there a possibility that a unused object getting escaped from garbage collector and be there on the heap until the end of the application.
Wanted to know because if it is there, then while coding i can be more cautious.
If an object is no longer referenced, it does still exist on the heap, but it is also free to be garbage-collected (unless we are talking Class objects, which live in PermGen space and never get garbage-collected - but this is generally not something you need to worry about).
There is no guarantee on how soon that will be, but your application will not run out of memory before memory from those objects is reclaimed.
However, garbage collection does involve overhead, so if you are creating more objects than you need to and can easily create less, then by all means do so.
Edit: in response to your comment, if an object is truly not referenced by anything, it will be reclaimed during garbage collection (assuming you are using the latest JVM from Sun; I can't speak toward other implementations). The reason why is as follows: all objects are allocated contiguously on the heap. When GC is to happen, the JVM follows all references to "mark" objects that it knows are reachable - these objects are then moved into another, clean area. The old area is then considered to be free memory. Anything that cannot be found via a reference cannot be moved. The point is that the GC does not need to "find" the unreferenced objects. If anything, I would be more worried about objects that are still referenced when they are not intended to be, which will cause memory leaks.
You should know that, before a JVM throws an out-of-memory exception, it will have garbage collected everything possible.
If an instance is no longer referenced, it is a possible candidate for garbage collection. This means, that sooner or later it can be removed but there are no guaranties. If you do not run out of of memory, the garbage collector might not even run, thus the instance my be there until the program ends.
The CG system is very good at finding not referenced objects. There is a tiny, tiny chance that you end up keeping a weird mix of references where the garbage collector can not decide for sure if the object is no longer referenced or not. But this would be a bug in the CG system and nothing you should worry about while coding.
It depends on when and how often the object is used. If you allocate something then deallocate (i.e., remove all references to it) it immediately after, it will stay in "new" part of the heap and will probably be knocked out on the next garbage collection run.
If you allocate an object at the beginning of your program and keep it around for a while (if it survives through several garbage collections), it will get promoted to "old" status. Objects in that part of the heap are less likely to be collected later.
If you want to know all the nitty-gitty details, check out some of Sun's gc documentation.
Yes; imagine something like this:
Foo foo = new Foo();
// do some work here
while(1) {};
foo.someOp(); // if this is the only reference to foo,
// it's theoreticaly impossible to reach here, so it
// should be GC-ed, but all GC systems I know of will
// not Gc it
I am using definition of: garbage = object that can never be reached in any execution of the code.
Garbage collection intentionally makes few guarantees about WHEN the objects are collected. If memory never gets too tight, it's entirely possible that an unreferenced object won't be collected by the time the program ends.
The garbage collector will eventually reclaim all unreachable objects. Note the "eventually": this may take some time. You can somewhat force the issue with System.gc() but this is rarely a good idea (if used without discretion, then performance may decrease).
What can happen is that an object is "unused" (as in: the application will not use it anymore) while still being "reachable" (the GC can find a path of references from one of its roots -- static fields, local variables -- to the object). If you are not too messy with your objects and structures then you will not encounter such situations. A rule of thumb would be: if the application seems to take too much RAM, run a profiler on it; if thousands of instances of the same class have accumulated without any apparent reason, then there may be some fishy code somewhere. Correction often involves explicitly setting a field to null to avoid referencing an object for too long.
This is theoretically possible (there is no guarantee the GC will always find all objects), but should not worry you for any real application - it usually does not happen and certainly does not affect a significant chunk of memory.
In theory, the garbage collector will find all unused objects. There could, of course, be bugs in the garbage collector…
That said, "In theory there is no difference between theory and practice, in practice, there is." Under some, mostly older, garbage collectors, if an object definition manages to reach the permanent generation, then it will no longer be garbage collected under any circumstances. This only applied to Class definitions that were loaded, not to regular objects that were granted tenured status.
Correspondingly, if you have a static reference to an object, that takes up space in the "regular" object heap, this could conceivably cause problems, since you only need to hold a reference to the class definition from your class definition, and that static data cannot be garbage collected, even if you don't actually refer to any instances of the class itself.
In practice though, this is a very unlikely event, and you shouldn't need to worry about it. If you are super concerned about performance, then creating lots of "long-lived" objects, that is, those that escape "escape-analysis", will create extra work for the garbage collector. For 99.99% of coders this is a total non-issue though.
My advice - Don't worry about it.
Reason - It is possible for a non-referenced object to stay on the heap for some time, but it is very unlikely to adversely affect you because it is guaranteed to be reclaimed before you get an out of memory error.
In general, all objects to which there are no live hard references, will be garbage-collected. This is what you should assume and code for. However, the exact moment this happens is not predictable.
Just for completeness, two tricky situations [which you are unlikely to run into] come into my mind:
Bugs in JVM or garbage collector code
So called invisible references - they rarely matter but I did have to take them into account one or two times during the last 5 years in a performance-sensitive application I work on

Categories

Resources