JVM
本地方法接口和本地方法栈
JDK
版本:1.8
使用Java
代码调用非Java
代码的接口称作为Native Method
。该方法的实现由非Java
语言实现,比如C
或者C++
。这是Java Doc中给出的解释
:A native method is a Java method whose implementation is provided by non-java code.
在定义一个Native Method
时,并不提供实现体(类似于Java
中的interface
),并不关系其底层是使用哪种语言、如何进行具体实现的。
本地接口的作用是融合不同的编程语言为Java
所用:
标识符native
可以与其它java
标识符连用,但是abstract
除外:
public class IHaveNatives{
public native void methodNative1(int x);
public native static long methodNative2();
private native synchronized float methodNative3(Object o);
native void methodNative4(int[] ary) throws Exception;
}
Java
语言使用起来非常方便,然而有些层次的任务用Java
实现起来不容易,或者开发者对程序的效率很在意时。就可以使用Native Method
方法解决。
与Java
环境的交互:
有时Java
应用需要与Java
外面的环境进行交互,这是本地方法存在的主要原因。当Java
需要与一些底层系统,如操作系统或某些硬件交换信息的场景。本地方法正是这样的一种交流机制:Native Method
提供了一个非常简洁的接口,开发者无需了解Java
应用之外的繁琐实现细节,直接调用接口即可。
与操作系统的交互:
JVM
支持着Java
语言本身和运行时库,它是Java
程序赖以生存的平台,它由一个字节码解释器和一些连接到本地代码的库组成。但是着并不是一个完整的系统,它经常需要依赖于一些底层系统的支持,这些底层系统都是非常强大的操作系统。通过调用本地方法接口,使得Java
很容易地实现了jre
与底层操作系统之间的交互,甚至JVM
的一些部分就是使用C
语言编写的。如果需要使用一些Java
语言本身没有提供封装的操作系统特性时,也需要使用本地方法。
Sun’s Java:
Sun
公司的解释器是使用C
语言进行实现的,着使得它能像一些普通的C
语言一样与外部进行交互。jre
大部分是用Java
语言编写的,它通过本地方法接口与外界进行交互。例如:java.lang.Thread
的setPriority()
方法就是使用Java
语言实现的,但是它正真实现调用的是该类中的本地方法setPriority()
方法。这个本地方法是使用C
语言进行实现的,并被植入JVM
内部,在Windows 95
的平台上这个本地方法最终将调用Win32 setPriority() API
。这是一个本地方法的具体实现由JVM
直接提供,更多的情况是本地方法由外部的动态链接库(external dynamic link library
)提供,然后被JVM
调用。
Java
虚拟机栈用于管理Java
方法的调用,而本地方法栈用于管理本地方法的调用。本地方法栈也是线程私有的。
本地方法栈允许被实现成固定或者是可动态扩展的内存大小,在内存溢出方面是相同的。
Java
虚拟机将会抛出一个StackOverflowError
错误。Java
虚拟机将会抛出一个StackOverflowError
错误。本地方法是由C
语言实现的。它的具体做法是Native Method Stack
中登记native
放啊,在Execution Engine
执行时加载本地方法库。
当某一个线程调用一个本地方法时,它就进入了一个全新的并且不再受JVM
虚拟机管控的空间,它和JVM
虚拟机拥有相同的权限。
并不是所有的JVM
都支持本地方法,因为Java
虚拟机规范并没有明确要求本地方法栈的使用语言、具体实现方式、数据结构等。如果JVM
产品不打算支持native
方法,也可以无需实现本地方法栈。在Hotspot
虚拟机中直接将本地方法栈和虚拟机栈合并在一起。