本地方法栈
:::primary
参考博客:java调用本地方法–jni简介
:::
什么是本地方法?
定义:[采用非 Java 代码实现的“接口”]{.red}
本地方法并不需要采用 Java 实现,[类似于]{.blue} 接口和抽象类中的方法
但是本地方法依然会采用其他语言具体实现,所以也只是类似于接口和抽象类
// 本地方法是没有方法体的,也就没有具体的实现,类似于接口和抽象类
public native void nativeMethod();
细节:
- Java 本地方法大多数采用 C/C++ 实现
- Java 本地方法可以通过本地方法接口(JNI)访问 Java 运行时数据区
- Java 线程调用本地方法后就不再受到虚拟机限制,可以访问操作系统的寄存器、内存等硬件设备
为什么需要使用本地方法?
+++danger 核心:Java 需要和操作系统级别的软件进行交互]
① Java 采用虚拟机隔离了操作系统,所以才能够实现跨平台
② 正是因为虚拟机隔离了操作系统,所以 Java 难以直接和操作系统建立联系,本地方法就提供了访问操作系统的接口
+++
+++ Java 需要使用某些采用其他语言实现的功能
① 虚拟机内部的解释器就是采用 C 实现的
② Java 想要使用虚拟机提供的某些方法就不得不提供链接其他语言的接口
+++
如何编写本地方法?!!草,网上查到的全是在 Linux 下编写的,就离谱,大致过程还是记录下!!{.bulr}
方式:[JNI(Java Native Interface)]{.blue}
:::info
① Java 借助本地调用接口使用存放在库文件中的本地方法,从而使用操作系统提供的功能
② Windows 库文件是采用 DLL 格式存方法的,Linux 库文件是采用 SO 格式存放的
:::
编写过程:
(1) 编写 Java 代码
public class NativeMethod
{
// 调用静态链接库
static {
try
{
System.loadLibrary("nativeMethod");
}
catch (Exception e)
{
System.err.println("fail...");
}
System.out.println("success...");
}
public static void main(String[] args)
{
// 调用本地方法
new NativeMethod().nativeMethod("Fuyusakaiori");
}
// 声明本地方法
private native void nativeMethod(String name);
}(2) 利用 javah 程序生成相应的 jni 文件
:::primary
① IDEA 中配置 javah 程序:配置并使用 JNI
② 直接在命令行中使用 javah 指令可能无法被识别,即使你配置了环境变量
:::
(3) 采用 C/C++ 编写方法的具体实现
// 头文件记得换成你自己 JNI 生成的文件
// 函数名
JNIEXPORT jstring JNICALL chapter06_NativeMethod_nativeMethod
(JNIEnv* env, jclass jc, jstring name)
{
// 返回传入的名称
return name;
}(4) 编译 C/C++ 源文件
gcc -D_REENTRANT -fPIC -l $Java_HOME$\include -l $Java_HOME$\include\win32 -c nativeMethod.c
(5) 后续暂时不记录了,因为有问题
特点:JNI 调用本地方法会导致开发的程序跨平台性能变差
什么是本地方法栈?
核心:基本内容和虚拟机栈完全相同
定义:存储被调用的本地方法拥有的信息
特点:
- [本地方法栈完全采用 C 语言实现]{.red}
- [本地方法栈也不存在垃圾回收机制,但是能够抛出 StackOverFlowError 异常和 OutOfMemoryError 异常]{.blue}
- [本地方法栈也是线程私有空间]{.blue}
细节:
- Java 虚拟机规范没有明确说明虚拟机必须实现本地方法栈,所以本地方法栈是可以没有的
- HotSpot 虚拟机中直接将虚拟机栈和本地方法栈合二为一