Are there any objects that are not subject to garbage collection? - java

In java(1.6 or earlier) , are there any type of objects that are not subject to garbage collection?

All java objects are subject to garbage collection. However native resources are not directly managed by the garbage collector, some like window handles (JFrame) are freed by the garbage collector when a finalize() method is implemented others need manual resource management.
Also the jvm does not have to collect existing objects before it shuts down, this can cause subtle bugs like data not being flushed to disk.
Last there are extensions to the java spec for real time systems or smart cards which include unmanaged memory for performance and resource reasons. However this does not apply to the standard jvm.

Maybe you have heard about weak, soft and phantom references. Check this
http://weblogs.java.net/blog/2006/05/04/understanding-weak-references

It depends what you mean by saying 'objects'. All primitive types except string and all data that was not allocated on the JVM heap (using operator new) are not subject to GC. Everything else is subject to GC.

Depending on the implementation even static fields are kept in an "object" (which you can see in a heap dump) which are cleaned up when the Class is discarded.
What you could be referring to is proxied data structures. These include GUI components, Threads, and direct/memory mapped ByteBuffers. In every case, the Object is on the heap, however there are data structure(s) not on the heap.

Related

How to do user control cache eviction/ garbage collection in java?

I have a situation where there are 2 files A and B, and data is being written continuously in both of them (like a stream).
Now I know that both files A and B are going to be competing for memory and the garbage collector is going to decide what page for what file will be replaced.
I want to control garbage collection by making the garbage collector favor file A (i.e. garbage collector should always choose eviction of pages of file B compared to A). Other possibility is to force writing of file B to disk instead of caching in memory.
Can these things happen in java?
I suspect you are confusing memory management with garbage collection. Yes, garbage collection is a form of memory management, but it's not what you are talking about when discussing "which pages of memory will be swapped out to disk when memory space is low" That's not garbage collection because there are still active references to the A and B files. The Garbage Collector won't do anything until there are no references to an object.
You want to control memory page swapping not garbage collection. I'm sure I'll be corrected in comments if I'm wrong about this, but I don't think you can control in Java which pages of memory get swapped to disk when available memory is low.
You cannot forcefully ask Java to do garbage collection.
But you can call System.gc() to request the JVM to do a garbage collection.
To make sure an object is ready for garbage collection you can assign it to null. That way you can make sure that when the garbage collector runs it gets this object and is removed from the heap.
Java has automatic garbage collection and identifies which objects are in use and which are not, and deleting the unused objects.
A good source about garbage collection within Java is here
The description of your problem lacks certain details, specifically, are the writes to your files sequential or is there random access involved?
As geneSummons correctly points out, you have memory management in the JVM confused with that of the Operating System. Even sun.misc.Unsafe will not allow you control over paging activity at the OS level from a Java application.
What you may want to look at is using memory mapped files, but that does depend on whether you are using random access for your writes. If all you're doing is writing sequentially this is most likely no use. Although this does not give you control over the paging of the files at the OS level it may provide you with a more efficient way of solving your problem.
There is a useful article on this subject, https://howtodoinjava.com/java-7/nio/java-nio-2-0-memory-mapped-files-mappedbytebuffer-tutorial/

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.

Deleting Dynamic array in java

In C++, dynamically allocated array has to be deleted unless it is lost in the memory. In java, do we have to do the same, and if so. How do you do that
In the Java programming language, dynamic allocation of objects is achieved using the new operator. An object once created uses some memory and the memory remains allocated till there are references for the use of the object. When there are no references for an object, it is assumed to be no longer needed and the memory occupied by the object can be reclaimed.There is no explicit need to destroy an object as java handles the de-allocation automatically. The technique that accomplishes this is known as Garbage Collection.Programs that do not de-allocate memory can eventually crash when there is no memory left in the system to allocate. These programs are said to have memory leaks.
In Java,Garbage collection happens automatically during the lifetime of a java program, eliminating the need to de-allocate memory and avoiding memory leaks.
In C language, it is the programmer’s responsibility to de-allocate memory allocated dynamically using free() function.
Read more at http://www.javatutorialhub.com/java-garbage-collection.html#wpewoJfMWffgXd8O.99
I don't understand your definition of dynamic array. Do you mean a collection of items where its length is unknown initialiazing it? If yes, you're talking about collections such as an ArrayList.
You don't have to worry about the deletion of your objects. The JVM will take care of your objects when they're not used anymore or when they're out of scope.
The JVM analyses the execution of your code and it will invoke a special component, named Garbage Collector, that it will clean the execution code from useless/out of scope objects.
For example, when you have this code:
if(condition)
{
string myStr = "test";
//other code here
}
The variable myStr, because it's not used anymore (it's out of scope of the if statement), will be marked by the JVM to be garbage collected.
The developer need not worry about deallocating the memory in java. The Java Garbage Collector do that for you. You can read how it works here

Are Java DirectByteBuffer wrappers garbage collected?

I understand that when a directbytebuffer is allocated, its not subject to garbage collection, but what I'm wondering is if the wrapping object is garbage collected.
For example, if I allocated a new DirectByteBuffer dbb, and then duplicated(shallow copied) it using dbb.duplicate(), I'd have two wrappers around the same chunk of memory.
Are those wrappers subject to garbage collection? If I did
while(true){
DirectByteBuffer dbb2 = dbb.duplicate();
}
Would I eventually OOM myself?
In the Sun JDK, a java.nio.DirectByteBuffer—created by ByteBuffer#allocateDirect(int)—has a field of type sun.misc.Cleaner, which extends java.lang.ref.PhantomReference.
When this Cleaner (remember, a subtype of PhantomReference) gets collected and is about to move into the associated ReferenceQueue, the collection-related thread running through the nested type ReferenceHandler has a special case treatment of Cleaner instances: it downcasts and calls on Cleaner#clean(), which eventually makes its way back to calling on DirectByteBuffer$Deallocator#run(), which in turn calls on Unsafe#freeMemory(long). Wow.
It's rather circuitous, and I was surprised to not see any use of Object#finalize() in play. The Sun developers must have had their reasons for tying this in even closer to the collection and reference management subsystem.
In short, you won't run out of memory by virtue of abandoning references to DirectByteBuffer instances, so long as the garbage collector has a chance to notice the abandonment and its reference handling thread makes progress through the calls described above.
A direct ByteBuffer object is just like any other object: it can be garbage-collected.
The memory used by a direct buffer will be released when the ByteBuffer object is GC'd (this is not explicitly stated for ByteBuffer, but is implied by the documentation of MappedByteBuffer).
Where things get interesting is when you've filled your virtual memory space with direct buffers, but still have lots of room in the heap. It turns out that (at least on the Sun JVM), running out of virtual space when allocating a direct buffer will trigger a GC of the Java heap. Which may collect unreferenced direct buffers and free their virtual memory commitment.
If you're running on a 64-bit machine, you should use -XX:MaxDirectMemorySize, which puts an upper limit on the number of buffers that you can allocate (and also triggers GC when you hit that limit).
Looking at the source code to DirectByteBuffer it just returns a new instance, so no, you won't OOM yourself.
As long as the rest of your code doesn't hold onto a reference to the original dbb then that object will get garbage collected as normal. The extra dbb2 objects will similarly get garbage collected when there is no longer any reference to them(ie, the end of the while loop).
Both the Java object and the native memory are freed at the same time by the garbage collector.
However, note that because the garbage collector doesn’t work well at cleaning up direct buffers, it’s best to allocate and reuse long-lived direct buffers instead of creating and abandoning new ones.
when a directbytebuffer is allocated, its not subject to garbage
collection
Where did you get that idea? It's not correct. Are you getting them mixed up with MappedByteBuffers?

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