This question already has answers here:
Is there a destructor for Java?
(24 answers)
Closed 8 years ago.
In C++ , if we create our own constructor then we need to require to deallocate the memory of the object created during construction call.(Correct me if i am wrong)
i want to know about JAVA constructor call. for java also do we require to deallocate memory of the object created or it will deallocate by their own if the object is not in use
In the Java, 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.
In Java,Garbage collection happens automatically during the lifetime of a java program, eliminating the need to de-allocate memory and avoiding memory leaks.
To read more visit.
In C++ , if we create our own constructor then we need to require to
deallocate the memory of the object created during construction
call.(Correct me if i am wrong)
CORRECT!
i want to know about JAVA constructor call. for java also do we
require to deallocate memory of the object created or it will
deallocate by their own if the object is not in use
Java uses constructors to create objects but there is no concept of desctructors in Java. Because Java is a garbage collected language and hence destruction of object is taken care by JVM instead of desctructor.
Related
This question already has answers here:
Where does the JVM store primitive variables?
(3 answers)
Closed 9 years ago.
I know Stack memory stores primitive types and the addresses of objects and the object values are stored in heap memory.
But if primitive is part of object then where it will be stored in Heap or Stack ?
How can I verify it ?
Thanks.
The stack is used for only local primitives and references to objects that is in the scope of a method (or block within) and not a class. The heap is used for all object data including the primitive fields thereof.
I think that it's not possible to know whether any data in the JVM is allocated on the stack or the heap. For example, for Hotspot, see: http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#escapeAnalysis
In Hotspot, you could turn off Escape Analysis, in which case I think it will always be allocated on the heap, but I wouldn't like to guarantee it (it depends on the internal workings of the JVM).
As for determining if something is allocated on the heap, you could use jmap to take a heap dump, and analyze it using jhat (or another similar tool). Then you should be able to inspect the contents of the heap.
We have the concept of pointers in C++. Now if we allocate some memory in C++ and pass it on to Java as an object reference(using JNI) then who should be and who will be freeing it.
Will it be
1.)The Garbage collector does it automatically in Java?
2.)We need to explicitly do a delete on the pointer in the wrapped JNI class finalize method?
3.)Or we should just forget finalize(as finalizers cannot be trusted) and it is responsibility of Java to call a C++ code which deletes the object
4.)Or is there some way to deallocate the memory directly in Java itself (not sure how Java intreprets a C++ pointer inorder to delete it)?
What is the best practice for doing this and vice versa(when we pass objects from Java to C++)?
We have the concept of pointers in C++. Now if we allocate some memory in C++ and pass it on to Java as an object reference(using JNI) then who should be and who will be freeing it.
The best strategy is usually to have the allocator also be the one to free the data.
1.)The Garbage collector does it automatically in Java?
The problem with this is you don't know when, if ever it will run.
2.)We need to explicitly do a delete on the pointer in the wrapped JNI class finalize method?
Better to have a release() method in Java rather than imply that C++ has to delete it. You may want C++ to recycle the memory.
3.)Or we should just forget finalize(as finalizers cannot be trusted) and it is responsibility of Java to call a C++ code which deletes the object
If you mean, allocate the memory in Java and pass it to C++ to populate. This is my preference.
I would use can use ByteBuffer.allocateDirect() and you can call ((DirectBuffer) buffer).cleaner().clean(); to clean it up deterministically.
This can make recycling the memory simpler, possibly the same buffer can be used for the life of the application.
I'm working on wrapping a C DLL library to Java using JNA. The library has provided a C# wrapper. In the constructor of C# wrapper, a object is created and the memory of the object is pinned by
this.m_object = _CreateObject();
this.m_objectGCH = GCHandle.Alloc(this.m_object, GCHandleType.Pinned);
m_object is an integer pointing to the created object, and the memory of the object is pinned by GCHandle.Alloc(). I can create a object and get the pointer to the object by JNA. However, I have no idea to pin the object memory in Java.
Java's GC has no awareness of the native memory allocated for your object. If you are responsible for deleting the memory at some future point, you must do so explicitly in your Java code by calling whatever "free" method is recommended by your object allocation.
If you need to ensure that Java does not GC a given Java object, then you need to ensure there is a reference to it until you no longer need it (the easiest way to do so is by storing it in a static (class) variable).
I've never seen such statements though,does it exist in java world at all?
Java's version of malloc is new -- it creates a new object of a specified type.
In Java, memory is managed for you, so you cannot explicitly delete or free an object.
Java has a garbage collector. That's why you never see such statements in your code(which is nice if you ask me)
In computer science, garbage
collection (GC) is a form of automatic
memory management. It is a special
case of resource management, in which
the limited resource being managed is
memory. The garbage collector, or just
collector, attempts to reclaim
garbage, or memory occupied by objects
that are no longer in use by the
program. Garbage collection was
invented by John McCarthy around 1959
to solve problems in Lisp.
new instead of malloc, garbage collector instead of free.
No direct equivalents exist in Java:
C malloc creates an untyped heap node and returns you a pointer to it that allows you to access the memory however you want.
Java does not have the concept of an untyped object, and does not allow you to access memory directly. The closest that you can get in Java to malloc would be new byte[size], but that returns you a strongly typed object that you can ONLY use as a byte array.
C free releases a heap node.
Java does not allow you to explicitly release objects. Object deallocation in Java is totally in the hands of the garbage collector. In some cases you can influence the behaviour of the GC; e.g. by assigning null to a reference variable and calling System.gc(). However, this does not force the object to be deallocated ... and is a very expensive way to proceed.
If you are up to no good (tm) I suppose you can get access to raw memory though the JNI interface. This is where you can call C programs from Java Programs. Of course you have to be running in an environment where your program has the privileges to do so (a browser won't normally allow this unless it is suicidal) but you can access objects via C pointers that way.
I sort of wonder where the original question is coming from. At one point long ago I was totally skeptical of the notion that C-style memory management and C-style pointers were not needed, but at this point I am true believer.
When I'm building a java object using JNI methods, in order to pass it in as a parameter to a java method I'm invoking using the JNI invocation API, how do I manage its memory?
Here's what I am working with:
I have a C object that has a destructor method that is more complex that free(). This C object is to be associated with a Java object, and once the application is finished with the Java object, I have no more need for the C object.
I am creating the Java object like so (error checking elided for clarity):
c_object = c_object_create ();
class = (*env)->FindClass (env, "my.class.name");
constructor = (*env)->GetMethodID (env, class, "<init>", "(J)V");
instance = (*env)->NewObject (env, class, constructor, (jlong) c_object);
method = (*env)->GetMethodID (env, other_class, "doSomeWork", "(Lmy.class.name)V");
(*env)->CallVoidMethod (env, other_class, method, instance);
So, now that I'm done with instance, what do I do with it? Ideally, I'd like to leave the garbage collection up to the VM; when it's done with instance it would be fantastic if it also called c_object_destroy() on the pointer I provided to it. Is this possible?
A separate, but related question has to do with the scope of Java entities that I create in a method like this; do I have to manually release, say, class, constructor, or method above? The JNI doc is frustratingly vague (in my judgement) on the subject of proper memory management.
The JNI spec covers the issue of who "owns" Java objects created in JNI methods here. You need to distinguish between local and global references.
When the JVM makes a JNI call out to native code, it sets up a registry to keep track of all objects created during the call. Any object created during the native call (i.e. returned from a JNI interface function) are added to this registry. References to such objects are known as local references. When the native method returns to the JVM, all local references created during the native method call are destroyed. If you're making calls back into the JVM during a native method call, the local reference will still be alive when control returns back to the native method. If the JVM invoked from native code makes another call back into the native code, a new registry of local references is created, and the same rules apply.
(In fact, you can implement you're own JVM executable (i.e. java.exe) using the JNI interface, by creating a JVM (thereby receiving a JNIEnv * pointer), looking up the class given on the command line, and invoking the main() method on it.)
All references returned from JNI interface methods are local. This means that under normal circumstances you do not need to manually deallocate references return by JNI methods, since they are destroyed when returning to the JVM. Sometimes you still want to destroy them "prematurely", for example when you lots of local references which you want to delete before returning to the JVM.
Global references are created (from local references) by using the NewGlobalRef(). They are added to a special registry and have to be deallocated manually. Global references are only used for Java object which the native code needs to hold a reference to across multiple JNI calls, for example if you have native code triggering events which should be propagated back to Java. In that case, the JNI code needs to store a reference to a Java object which is to receive the event.
Hope this clarifies the memory management issue a little bit.
There are a couple of strategies for reclaiming native resources (objects, file descriptors, etc.)
Invoke a JNI method during finalize() which frees the resource. Some people recommend against implementing finalize, and basically you can't really be sure that your native resource is ever freed. For resources such as memory this is probably not a problem, but if you have a file for example which needs to be flushed at a predictable time, finalize() probably not a good idea.
Manually invoke a cleanup method. This is useful if you have a point in time where you know that the resource must be cleaned up. I used this method when I had a resource which had to be deallocated before unloading a DLL in the JNI code. In order to allow the DLL to later be reloaded, I had to be sure that the object was really deallocated before attempting to unload the DLL. Using only finalize(), I would not have gotten this guaranteed. This can be combined with (1) to allow the resource to be allocated either during finalize() or at the manually called cleanup method. (You probably need a canonical map of WeakReferences to track which objects needs to have their cleanup method invoked.)
Supposedly the PhantomReference can be used to solve this problem as well, but I'm not sure exactly how such a solution would work.
Actually, I have to disagree with you on the JNI documentation. I find the JNI specification exceptionally clear on most of the important issues, even if the sections on managing local and global references could have been more elaborated.
Re: "A separate, but related question"... you do not need to manually release jclass, jfieldID and jmethodID when you use them in a "local" context. Any actual object references you obtain (not jclass, jfieldID, jmethodID) should be released with DeleteLocalRef.
The GC would collect your instance, but it will not automatically release the non-java heap memory allocated in the native code. You should have explicit method in your class to release the c_object instance.
This is one of the cases where I'd recommend using a finalizer checking if c_object has been released and release it, logging a message if it's not.
A useful technique is to create a Throwable instance in the Java class constructor and store it in a field (or just initialize the field inline). If the finalizer detects that the class has not been properly disposed it would print the stacktrace, pinpointing the allocation stack.
A suggestion is to avoid doing straight JNI and go with gluegen or Swig (both generate code and can be statically linked).