Equivalent code to GCHandle.Alloc() in Java? - java

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).

Related

Object Memory Management Python Vs Java

Can some one explain on the way Python manages memory management during creation of an object in class.
For example in java we can only declare member variables and the initialisation part happens inside the constructor. That means memory used when an object is constructed.
But in python we can initialise a class variable outside the init method. Where is this data stored?
As a precursor, this question has already been answered here, this may also be a good reference. However, I will try to explain it again. The init method in Python is designed for conventional use and although a special method in the fact that it is reserved to go at the beginning of a method it is not required. Memory management in Python involves a private heap containing all Python objects and data structures. If you were to initialize a class variable outside the init method declaration, it would simply be stored in the heap along with those initialized in the init method. Hope this helps!

difference between C++ constructor and java Constructor [duplicate]

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.

JNI, Garbage collection and Pointers- Java/C++ who should do what?

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.

General Question: Java has the heap and local stack. Can you access any object from the heap?

I was really looking at the differences between pass by value and how Java allocates objects and what java does to put objects on the stack.
Is there anyway to access objects allocated on the heap? What mechanisms does java enforce to guarantee that the right method can access the right data off the heap?
It seems like if you were crafty and maybe even manipulate the java bytecode during runtime, that you might be able to manipulate data off the heap when you aren't supposed to?
There is no instruction in the JVM instruction set that gives arbitrary access to the heap. Hence, bytecode manipulation will not help you here.
The JVM also has a verifier. It checks the code of every method (as a class is being loaded) to verify that the method does not try to pop more values off the execution stack than what it had pushed onto it. This ensures that a method cannot "see" the objects pointed by its calling method.
Finally, local variables are stored in a per-method array (known as the "local variables array"). Again, the verifier makes sure that every read/write instruction from-/to- that array specifies an index that is less than the size of the array. Note that these JVM instructions can only specify a constant index. They cannot take a computed value and use it as an index.
So to recap, the answer is No.
All objects in Java are located on the heap. I'm not quite sure what you mean by "access objects from the heap". The only things stored on the stack are the list of functions which called into the current context and their local variables and parameters. All local variables and parameters are either primitive types or references.
If you allocate an object using new (which is the only way to allocate non-primitive types; yes this includes array types), then the object is allocated on the heap, and a reference to that object is stored on either the stack or the heap, depending on if the reference is stored in a local variable/parameter or as a member of another object.
When passed as parameters to functions, all objects are passed by reference - if the function modifies the parameter, the original object is also modified. Identically, one could also say that the object references are passed by value - if you change a parameter to refer to a new object, it will continue to refer to that object for the duration of the function, but the original object which was passed in will still refer to whatever it referred to before. Primitive types are also passed by value.
Regarding objects on the stack, it is only the new Java 6 VM from SUN (and perhaps some others) that will try to optimize byte code by putting objects on the stack. Typically, all objects will go into the heap. For reference, check out: http://www.ibm.com/developerworks/java/library/j-jtp09275.html
Also the JVM spec is at http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348. The JVM protects its heap by simply not giving you instructions needed to corrupt it. Flaws in JVM implementations may cause your mileage to vary.

JNI memory management using the Invocation API

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).

Categories