标签:java方法 数据结构 java标识符 rar imp float tail 硬件 本地
一个Native Method就是一个Java调用非Java代码的接口。一个Native Method是这样一个Java方法,该方法的实现由非Java语言实现。
"A native method is a Java method whose implementation is provided by non-java code."在定义一个native method时,并不提供实现体(有些像定义一个Java Interface) ,因为其实现体是由非java语言在外面实现的。本地接口的作用是融合不同的编程语言为Java所用,它的初衷是融合C/C++程序。
标识符 native 可以与其它Java标识符连用,但是 abstract 除外。如:
public class IHaveNatives {
public native void Native1(int x);
public native static long Native2();
private native synchronized float Native3(Object o);
native void Native4(int[] ary) throws Exception;
}
Navtive 方法是 Java 通过 JNI 直接调用本地 C/C++ 库,可以认为是 Native 方法相当于 C/C++ 暴露给 Java 的一个接口,Java 通过调用这个接口从而调用到 C/C++ 方法。当线程调用 Java 方法时,虚拟机会创建一个栈帧并压入 Java 虚拟机栈。当它调用的是 native 方法时,虚拟机会保持 Java 虚拟机栈不变,虚拟机只是简单地动态链接并直接调用指定的 native 方法。
当一个类第一次被使用到时,这个类的字节码会被加载到内存,并且只会加载一次。在这个被加载的字节码的入口维持着一个该类所有方法描述符的list,这些方法描述符包含这样一些信息:方法代码存于何处,它有哪些参数,方法的描述符(public之类)等等。
如果一个方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针。这些实现在一些DLL文件内,但是它们会被操作系统加载到java程序的地址空间。当一个带有本地方法的类被加载时,其相关的DLL并未被加载,因此指向方法实现的指针并不会被设置。当本地方法被调用之前,这些DLL才会被加载,这是通过调用java.system.loadLibrary()
实现的。
Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用。
当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。它和虚拟机拥有同样的权限。
当一个线程调用一个本地方法时,本地方法又回调虚拟机中的另一个Java方法。下面这幅图展示了java虚拟机内部线程运行的全景图。一个线程可能在整个生命周期中都执行Java方法,操作他的Java栈;或者他可能毫无障碍地在Java栈和本地方法栈之间跳转。
该线程首先调用了两个Java方法,而第二个Java方法又调用了一个本地方法,这样导致虚拟机使用了一个本地方法栈。图中的本地方法栈显示为 一个连续的内存空间。假设这是一个C语言栈,期间有两个C函数,他们都以包围在虚线中的灰色块表示。第一个C函数被第二个Java方法当做本地方法调用, 而这个C函数又调用了第二个C函数。之后第二个C函数又通过本地方法接口回调了一个Java方法(第三个Java方法)。最终这个Java方法又调用了一个Java方法(它成为图中的当前方法)。
就像其他运行时内存区一样,本地方法栈占用的内存区也不必是固定大小的,他可以根据需要动态扩展或者收缩。某些是实现也允许用户或者程序员指定该内存区的初始大小以及最大,最小值。
并不是所有的JVM都支持本地方法。因为Java虚拟机规范并没有明确要求本地方法栈的使用语言、具体实现方式、数据结构等。如果JVM产品不打算支持native方法,也可以无需实现本地方法栈。在Hotspot JVM中,直接将本地方法栈和虚拟机栈合二为一。
JVM学习-05:JVM之本地方法(Native Method)与本地方法栈(Native Method Stack)
标签:java方法 数据结构 java标识符 rar imp float tail 硬件 本地
原文地址:https://www.cnblogs.com/itzlg/p/13287935.html