栈空间-本地方法栈

本地方法栈

:::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++ 编写方法的具体实现

    #include "stdio.h"
    // 头文件记得换成你自己 JNI 生成的文件
    #include "chapter06_NativeMethod.h"

    // 函数名
    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 虚拟机中直接将虚拟机栈和本地方法栈合二为一
Author: Fuyusakaiori
Link: http://example.com/2021/09/23/jvm/runtime/stackspace/本地方法栈/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.