What is a native peer? - java

Native peer is defined in Effective Java (2nd) as following
A second legitimate use of finalizers concerns objects with native peers. A native peer is a native object to which a normal object delegates via native methods. Because a native peer is not a normal object, the garbage collector doesn’t know about it and can’t reclaim it when its Java peer is reclaimed.
In another question java peer is explained with example. Is it the java class PrintHello or another class which uses PrintHello?
What part is being called a Native Peer here and which part is Java Peer, any example? I understand the use of finalize, I am only confused about which part native peer is being referred to.

A native object is not programmed only in java, but in a platform specific language, typically c or assembler.
Memory allocated by this code cannot be disposed by the GC. Therefore you may need to clean it in a finalizer.
The native peer is the native part of a Java object.
You can see a nice example here:
https://www.javaworld.com/article/2077520/learn-java/java-tip-23--write-native-methods.html

A simple example would be a native window vs. a JFrame. A JFrame is a Java peer, but it needs a (platform dependent) native peer to actually display graphics.
This is why you need to call dispose() when getting rid of a JFrame. You need to get rid of the native component explicitly, because the GC can't touch it.

Related

Does Garbage Collector run in JVM created from C++?

I have a C++ codebase, in which I'm using JNI to create a JVM and occasionally interact with a library implemented in Java. I'm curious whether, in this use case, Java's garbage collector will still reliably run and clean up?
Most of the information that I find online about JNI seems to be about the "opposite" use case, where people generally appear to have mainly Java code, which sometimes interacts with native code through JNI. For such a use case, I find for example the following online:
The automatic garbage collection of local references that are no longer in scope prevents memory leaks in most situations. This automatic garbage collection occurs when a native thread returns to Java (native methods) or detaches from the JVM (Invocation API). Local reference memory leaks are possible if automatic garbage collection does not occur. A memory leak might occur if a native method does not return to the JVM, or if a program that uses the Invocation API does not detach from the JVM.
I'm not sure what exactly "returns to Java" in this context means. Is just occasionally calling into Java-based methods from C++ sufficient, does that already count as "returning to Java"? If not, are there any ways to make sure that the garbage collector gets a chance to run in my use case?
The JVM created with JNI is a full JVM, including GC.
Think of it this way: The java command that you normally use to run Java programs, is nothing but a small JNI program that creates a JVM, locates the class named on the command-line, and makes a static call to the main(String[]) method.

Monitor jvm heap size from C++

Is there a way to programmatically get the current jvm stats such as classes loaded or current heap size from C++? I know there are many tools to do so but I would like to integrate this with another application that would read these statistics from time to time.
You can have a look at JVMTI and JNI.
JVMTI allows you to attach a native agent to a Java application, with loads of low-level functionalities like heap traversals, etc. It also contains "Garbage Collection Start" & "Garbage Collection Finish" events, which could be used as starting points.
JNI allows you to call Java functions from native code (and vic-versa). I could imagine that you could use this technique to obtain information from ManagementFactory or some similar Java class that provides the needed information. This post contains a complete example on how to call static Java methods via JNI, which should be a good starting point.

What is meant by "AWT widgets written in Java which delegated to peer classes that were written in C"?

I don't understand the meaning of
The original Java AWT was implemented by having widgets written in Java which delegated to peer classes that were written in C
The "peer classes that were written in C" part:
It means Java classes included native code?
Hotspot Java has substantial parts of the runtime system written in C / C++. At one point, this included the AWT peer classes. (And it still may do ... )
The native code is not "in" the Java. Rather, the Java typically has native method declarations that typically get bound to a native implementation when the corresponding native library is loaded.
(But don't take this as a green light do the same thing in your code. Interfacing with native code is tricky, and if you get it wrong you are liable to trigger hard JVM crashes ... and a world of pain ...)
I understood now. The AWT toolkit used native components by using C code in peer classeswhich is solved in Swing. Thank u #Andrew

How JVM call the native method in host environment

These day I have been reading about Java Native Interface.So by the way I do have doubt.Let say for a instance,If we need to do a I/O operation in Java program, we exercise the Java API for I/O operations.Moreover,at low level, it should be mapped to OS level I/O handling.The doubt is how Java API interact with native I/O methods in host operating system.
Short and Sweet, I heard some of the methods in JDK are implemented natively.How those native methods are called by Java API.I guess it would be JNI(Java Native Interface).
Could somebody clarify my doubts.
Thanks
Nuwan Arambage
Methods in Java can be marked native to indicate that their implementation is not written in Java or in bytecode, but rather in something platform-dependent. For example, Java I/O operations are almost always implemented as native methods so that they can take advantage of the underlying hardware or OS interface on the machine.
There is no guarantee whatsoever about how native methods are actually implemented. In Sun's (now Oracle's) implementation of the JVM, you can write implementations for native methods by using JNI to define specially-named C functions that interact with custom libraries in order to interface with Java code. However, another JVM could implement native methods in a totally different way. In fact, right now I'm working on a project to implement a JVM in JavaScript, and so all the native methods are implemented in JavaScript rather than C.
In short, there's no "one way" in which native methods are implemented. The whole point is to give maximum flexibility to the JVM and Java library implementations, and so the less specified the behavior is the better.
After a native library has been loaded, the methods are bound (integrated) into the JVM. The Java VM Spec uses the term binding rather then linking to avoid confusion. But that's just wording.
The rest is simple. There are some bytecode operands that are used to invoke a method. And if that message is declared native, then the associated native code is invoked. Parameters and results are converted so that it doesn't make a difference if we call a native or a non-native method.
Have a look at the spec of invokevirtual, the bulleted list covers the native case.

Reliabily unload dll in java

I am trying to unload a dll in java. I have read this and this but it seems that you can not guarantee that the dll will actually be unloaded at a certain time. This is because System.gc() simply "asks kindly" for the garbage collector to run.
So here is a break down of the situation. I have a dll that provides some functionality via JNI. Lets call this dll MainDll. MainDll is loaded from a call to System.load("MainDll"). I need to be able to unload and load this dll on the fly.
Is it possible to create another dll that's sole purpose is to load and unload MainDll. Lets call this dll LoaderDll. I could then simple call System.load("LoaderDll") and have some native functions to load and unload MainDll. The reason for doing this, is I have access to functions on the native system that can load and unload the dll on the fly. The tricky part with this is, will I have still be able to access the native functions I have written in MainDll if it loaded from inside LoaderDll.
Sorry if this is a confusing question. It seems its a little difficult to explain.
Thanks
Create a wrapper DLL that does the loading/unloading. Also have wrapper methods in the DLL that turn around and delegate the calls to the loaded MainDll DLL. This way your Java JNI code only knows about a single DLL. It can still request the unload [LoaderDll::unload()] which internally unloads the MainDll.
This should work as long as the methods/functions in LoaderDll can trigger a load of MainDll when they are called when MainDll is not currently loaded, assuming that is the desired behavior instead of throwing an exception/error.
One issue with this would be that LoaderDll would always be loaded.
Add a level of indirection.
Make your native methods call forwarding routines in LoaderDLL. The forwarding routines can use C facilities to forward the calls to code in mainDLL.
If you have a need to dynamically load and unload code, have you considered OSGi. This works in felix at least.
In Oracle/Sun's JDK, System.gc() will trigger a full gc (unless it has been turned off on the command line). It could be just a hint on other JVMs.
Based on your clarifying comments, I think the simplest approach would be to spawn a new JVM, whose sole responsibility is managing your DLL. Probably exposing an RMI interface to access those classes (although a simple stream may be sufficient).
I haven't still encountered a situation where System.gc() not to trigger the garbage collector although it is just a hint.
This tutorial actually helped me to do my work: Unload Java JNI DLL

Categories