Java garbage collect to hashtable - java

Does java collect the garbage-signed things as objects?
If yes, can i tell java to direct them to one of my hashtables(accepts objects right?) programmatically?
I am curious about this functionality.I know System.gc() is the command but how can i achieve first question? Can i?
myTrashBin=System.gc().getObjectList(); //???
If not, may be there could be a way to create this functionality by custom classes.
Last question: how can we override System.gc() ?
Thanks.

This isn't under your control. If your objects are unreachable then GC will collect these. System.gc() is nothing more than a hint, and can't be relied upon.
finalize() may be of interest, but read the answers to this question to understand limitations etc. PhantomReferences may also be of interest.

I think you can achieve something like that if you implement the Finalize method and writing the code there: maybe adding the object to a custom list
Called by the garbage collector on an object when garbage collection determines that there are no more references to the object
http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#finalize%28%29

System.gc() issues a call for the garbage collector but that's all there is to it. It might rise its priority and it might collect your items sooner, but there is no guarantee, as the docs say:
Calling the gc method suggests that the Java Virtual Machine expend effort toward
recycling unused objects in order to make the
memory they currently occupy available for quick reuse. When control
returns from the method call, the Java Virtual Machine has made a best
effort to reclaim space from all discarded objects.
You're better off taking other approaches such as the finalize() method or managing a reference counter in your objects so when it hits zero you know it is elegible to be collected. Check this link out.

Java uses managed memory. This means the JVM manages it because you don't want to ;)
can i tell java to direct them to one of my hashtables(accepts objects right?) programmatically?
You can progammatically get all the objects which would be cleaned up if they are referenced via a WeakReference.
how can we override System.gc() ?
You can't. In fact its only a hint as its not guaranteed to do anything.

Related

Prevent Java VM from finalizing an object

Is there any way to tell the Java VM (for this case, HotSpot or Zing) to no longer treat an objects as if there is a finalize method? Really, the whole class, I'm guessing, if at all possible.
I'm having problems with objects that have already had their resources freed but still put pressure on the VM that thinks it needs to call finalize on them.
This is in a library, so there is no way to change the class.
The use case is a library was written to clean up off-heap resources if you forgot or decided to let the GC do it for you. The problem is I get a lot of them hanging around.
Your only option would be to use an agent (-javaagent) that will override the finalize implementation with an empty one.
The JVM automatically creates a FinalReference object for each instance of a class with non-empty finalize (and this is how the JVM (Oracle) tracks the finalizable objects). You can't change his behavior.
The use case is a library was written to clean up off-heap resources if you forgot or decided to let the GC do it for you.
For that we use a Cleaner as ByteBuffer does. This is more light weight way of cleaning up resources.
EDIT Another option is you could
obtain the Finalizer.queue and remove elements yourself while holding the Finalizer.lock You could add a thread which periodically cleans up the queue of elements which don't need to be there.
you could replace this queue with your own implementation so it behaves differently. e.g. not add objects of a chosen class in the first place.
No, you can't do this. It's part of the JVM spec. Nor is it clear why you should do this; the VM will call finalize() if they have that method when they're cleaned up, regardless of what has happened previously. If you're calling finalize directly and triggering some kind of double finalize bug, then the answer is simple: "Don't do that"

JNI libraries deallocate memory upon garbage collection?

I am using JCUDA and would like to know if the JNI objects are smart enough to deallocate when they are garbage collected? I can understand why this may not work in all situations, but I know it will work in my situation, so my followup question is: how can I accomplish this? Is there a "mode" I can set? Will I need to build a layer of abstraction? Or maybe the answer really is "no don't ever try that" so then why not?
EDIT: I'm referring only to native objects created via JNI, not Java objects. I am aware that all Java objects are treated equally W.R.T. garbage collection.
Usually, such libraries do not deallocate memory due to garbage collection. Particularly: JCuda does not do this, and has no option or "mode" where this can be done.
The reason is quite simple: It does not work.
You'll often have a pattern like this:
void doSomethingWithJCuda()
{
CUdeviceptr data = new CUdeviceptr();
cuMemAlloc(data, 1000);
workWith(data);
// *(See notes below)
}
Here, native memory is allocated, and the Java object serves as a "handle" to this native memory.
At the last line, the data object goes out of scope. Thus, it becomes eligible for garbage collection. However, there are two issues:
1. The garbage collector will only destroy the Java object, and not free the memory that was allocated with cuMemAlloc or any other native call.
So you'll usually have to free the native memory, by explicitly calling
cuMemFree(data);
before leaving the method.
2. You don't know when the Java object will be garbage collected - or whether it will be garbage collected at all.
A common misconception is that an object becomes garbage collected when it is no longer reachable, but this is not necessarily true.
As bmargulies pointed out in his answer:
One means is to have a Java object with a finalizer that makes the necessary JNI call to free native memory.
It may look like a viable option to simply override the finalize() method of these "handle" objects, and do the cuMemFree(this) call there. This has been tried, for example, by the authors of JavaCL (a library that also allows using the GPU with Java, and thus, is conceptually somewhat similar to JCuda).
But it simply does not work: Even if a Java object is no longer reachable, this does not mean that it will be garbage collected immediately.
You simply don't know when the finalize() method will be called.
This can easily cause nasty errors: When you have 100 MB of GPU memory, you can use 10 CUdeviceptr objects, each allocating 10MB. Your GPU memory is full. But for Java, these few CUdeviceptr objects only occupy a few bytes, and the finalize() method may not be called at all during the runtime of the application, because the JVM simply does not need to reclaim these few bytes of memory. (Omitting discussions about hacky workarounds here, like calling System.gc() or so - the bottom line is: It does not work).
So answering your actual question: JCuda is a very low-level library. This means that you have the full power, but also the full responsibilities of manual memory management. I know that this is "inconvenient". When I started creating JCuda, I originally intended it as a low-level backend for an object-oriented wrapper library. But creating a robust, stable and universally applicable abstraction layer for a complex general-purpose library like CUDA is challenging, and I did not dare to tackle such a project - last but not least because of the complexities that are implied by ... things like garbage collection...
Java objects created in JNI are equal to all other Java objects, and are garbage collected and destroyed when their time comes. To keep such objects from being destroyed too early, we often use JNI function env->NewGlobalRef() (but its usage is by no ways limited to objects created in native).
On the other hand, native objects are not subject to garbage collection.
There are two cases here.
Native code allocates Java Objects. These objects are GC's like all other Java objects. If the native goofs up and holds strong references, it can prevent GC.
Native code allocates Native memory. The GC knows nothing about it; it's up to the library to arrange to free it. One means is to have a Java object with a finalizer that makes the necessary JNI call to free native memory.

Can I Force Garbage Collection in Java? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Forcing Garbage Collection in Java?
Can I Force Garbage Collection in Java by any means?
System.gc() is just a suggestion.It's useless.
When I know for sure that some resources won't be used any more,why can't I force to clean them?
Just like delete() in C++ and free() in C?
When there are lots of resources that can't be reused,this can really suck the performance.All that we can do is sleep().
Any solutions?Thanks
Nope, System.gc() is as close as you can get. Java isn't C or C++, the JVM manages memory for you, so you don't have that kind of fine grained control. If you set objects you're no longer using to null, or loose all references, they will get cleaned up. And the GC is pretty smart, so it should take good care of you.
That said, if you are on a unix box, and force a thread dump (kill -3), it'll pretty much force garbage collection.
You shouldn't be trying to force GC - if you are running low on memory then you have a memory leak somewhere. Forcing GC at that point won't help, because if you are holding a reference to the object then it still won't be garbage collected.
What you need to do is solve the real problem, and make sure you are not holding references to objects you are not using any more.
Some common culprits:
Holding lots of references in a large object graph that never get cleared up. Either set references to null when you don't need them any more, or better still simplify your object graph so it doesn't need all the extra long-term references.
Caching objects in a hashmap or something similar that grows huge over time. Stop doing this, or use something like Google's CacheBuilder to create a proper soft reference cache.
Using String.intern() excessively on large numbers of different strings over time.
References with larger scope than they need. Are you using an instance variable when it could be a local variable, for example?
There is no way to explicitly instruct the JVM to collect garbage. This is only performed when the system needs the resources.
The only two actions I'm aware of to potentially get the GC running are the following:
As you stated, attempt to "suggest" that GC now would be a good time by called System.gc().
Set any references you are not using to the null reference to make the elements eligible for collection.
On my second point, see the answer here: Garbage collector in java - set an object null. In essence, if you don't make the objects you don't need available for garbage collection (by losing the reference you have to it) then there is no reason for the garbage collector to run, because it's unaware of any available garbage.
In addition, it's important to consider why/how those objects in memory are affecting performance:
Are you getting lots of OutOfMemoryExceptions? This could be resolved by point #2 and by increasing the available heap space for the JVM.
Have you done measurements to see that more objects in the JVM's allocated heap space makes a difference in performance? Determining when you could let references to objects go earlier could help reduce these issues.

How does the GC know when to collect an object?

I know that the GC collects objects that have no references pointing to the object in question, but what happens in the event of listener objects?
Suppose you have an AnimationDelegate that listens to data from a DataSupplier. When the DataSupplier recieves data and fires off the event to the AnimationDelegate, the delegate will then invalidate (/update/redraw etc...) a Graphic. Now say the screen is disabled, removed or, through various means, the graphic can no longer draw and is collected. The AnimationDelegate is still registered to the DataSupplier. How will the GC know to collect it? Should one unregister the delegate in the graphics finalize() method?
I'm afraid the answer won't fit the format :) Start with this article by Brian Goetz: he's a perfect person to read if you're interested in GC.
Basically, as soon as object is not reachable from active threads, it's collected. The actual algorithms vary even within one JVM, but the point stays the same: what's not reachable is a garbage. What's reachable is not a garbage. Easy.
GC will not collect the Graphic in your example, as it's reachable from AnimationDelegate, which in turn is reachable (via subscription) from DataSupplier which is supposed to be reachable from some active thread. So the answer will be: your assumptions are wrong; GC will not collect anything here.
To answer your question, unsubscribe everything you don't need.
As #rfeak rightfully says, finalize() is a big no-no. It's almost impossible to use it properly, and it's way too easy to use it wrong. That said,it's OK to use it as a backup solution when you need to free resources. But generally your application has to be able to work just fine even if finalize() never gets called.
It all depends on the JVM you're using and the GC. Most default GC from the JDK use the so called "tracing collectors", which simply start at a given root set of objects and trace all the objects reachable from that set. All the other objects in memory are seen as garbage and deleted. So circular references aren't really a problem unless one of the objects is reachable from the root set.
What is the root set of objects? Well if memory serves right roots can be found in: program registers, local variables in each thread's stack and static variables.
To see if your objects will be GC'd we would know more about the design of your application.
#Edit: Oh and I almost forgot: Memory Management in the JavaHotSpotâ„¢ Virtual Machine. This is a pretty good overview of how it all works.
It will only know if you have removed the references (nulled them out).
However, don't do this on finalize(). Finalize is bad bad bad. There should be other lifecycle methods available for cleaning up listener(observer) type objects.
By the way, observer pattern is notorious for creating memory leaks because the GC couldn't collect due to lingering references.

regarding garbage collection.Why do we need to call System.gc();?

Garbage collection is called automatically when an object is refered to is no longer available to any variable. But I like know why do we call explicitly using System.gc() when garbage collection is called automatically.When do we call System.gc();
You don't. As you say, garbage collection is automatic. System.gc() doesn't even force a garbage collection; it's simply a hint to the JVM that "now may be a good time to clean up a bit"
In general, trying to force the garbage collector to do what you want with System.gc() is a hack applied by people who think they know better than they actually do, or as an (attempted) workaround for broken code.
I've been writing Java for years and I've yet to see a situation where calling System.gc was really the right thing to do (in anything I've written)
We don't.
We just don't.
Perhaps my experience is limited, but I have not once found it necessary to call System.gc().
I will quote Brian Goetz on the performance aspect (if you haven't heard of him, look him up -- and read the rest of this article, too):
A third category where developers often mistakenly think they are helping the garbage collector is the use of System.gc(), which triggers a garbage collection (actually, it merely suggests that this might be a good time for a garbage collection). Unfortunately, System.gc() triggers a full collection, which includes tracing all live objects in the heap and sweeping and compacting the old generation. This can be a lot of work.
In general, it is better to let the system decide when it needs to collect the heap, and whether or not to do a full collection.
You don't need it. Think of it as a diagnostic tool, like being able to write to a debug console.
For example, imagine that if you were doing benchmarking, you would want to tell the GC to collect garbage after each benchmark run.
You do need it. It is very useful no matter what these other people say.
A usage example:
Say that you have just finished a long background task that has used a lot of memory. None of those objects are going to be used again. Since the task took a long time the user isn't going to care about another 5-10 seconds. This is a good time to garbage collect.
If you don't GC at that point, it is going to happen later. Probably during interactive use of the program at which point the user experience gets choppy.

Categories

Resources