当前位置: 首页 > 后端技术 > Java

【无为原创】JVM的native方法栈和native方法接口详解

时间:2023-04-02 01:06:57 Java

上面我们讲了JVM的虚拟机栈,今天给大家分享JVM的native方法栈。什么是本地方法接口?简单的说,NativeMethod是Java调用非Java代码的接口。NativeMethod是一种Java方法,其实现是用非Java语言(例如C)实现的。此功能并非Java独有。许多其他编程语言都有这种机制。例如,在C++中,您可以使用extern"C"告诉C++编译器调用C函数。“本地方法是一种Java方法,其实现由非Java代码提供。”定义native方法时,不提供实现体(有的像定义java接口),因为实现体是由非java语言实现的。本地接口的作用是为Java集成不同的编程语言,其初衷是集成C/C++程序。#为什么要使用Native方法?Java使用起来非常方便,但是用Java实现一些任务并不容易,或者当我们关心程序的效率时,问题就出现了。与Java外部环境交互:有时Java应用程序需要与Java外部环境交互,这是本地方法存在的主要原因。你可以想到Java需要与一些底层系统交换信息的情况,比如操作系统或一些硬件。native方法就是这样一种通信机制:它为我们提供了一个非常简洁的接口,我们不需要了解Java应用程序之外的繁琐细节。与操作系统交互:JVM支持Java语言本身和运行时库。它是Java程序赖以生存的平台。它由一个解释器(解释字节码)和一些连接到本机代码的库组成。但是,它毕竟不是一个完整的系统,往往依赖于一些底层系统的支持。这些底层系统通常是功能强大的操作系统。通过使用native方法,我们可以使用Java实现jre与底层系统的交互,甚至JVM的某些部分是用C编写的。另外,如果我们想使用Java语言封装的操作系统的一些特性本身不提供,我们还需要使用native方法。Sun的JavaSun的解释器是用C实现的,这使得它可以像一些普通的C一样与外界进行交互。jre大部分是用Java实现的,它也通过一些native方法与外界进行交互。例如:类java.lang.Thread的setPriority()方法是Java实现的,但是它调用了类中的本地方法setPriority0()。这个native方法是用C实现的,植入到JVM内部。在Windows95平台上,这个本机方法最终将调用Win32SetPriority()API。这是JVM直接提供的本地方法的具体实现,更多的时候是本地方法由外部动态链接库(externaldynamiclinklibrary)提供,然后由JVM调用。native方法栈Java虚拟机栈用于管理Java方法的调用,native方法栈用于管理native方法的调用。本机方法堆栈也是线程私有的。允许实现为固定或动态可扩展的内存大小。(在内存溢出方面也是一样)如果线程请求的栈容量超过了native方法栈允许的最大容量,Java虚拟机就会抛出StackOverflowError异常。如果native方法栈是可以动态扩展的,而尝试扩展时无法申请到足够的内存,或者创建新线程时没有足够的内存创建对应的native方法栈,那么Java虚拟机就会抛出OutOfMemoryError异常。本机方法是使用C语言实现的。它的具体方法是在NativeMethodStack中注册native方法,在ExecutionEngine执行时加载native方法库。当线程调用native方法时,就进入了一个不再受虚拟机限制的全新世界。它具有与虚拟机相同的权限。本地方法可以通过本地方法接口访问虚拟机内部的运行时数据区。它甚至可以使用本机处理器中的寄存器直接从本机内存中的堆中分配任意数量的内存。并非所有JVM都支持本地方法。因为Java虚拟机规范并没有明确要求本地方法栈使用的语言、具体实现方法、数据结构等。如果JVM产品不打算支持nativemethods,则没有必要实现nativemethodstack。连续三个码字好不容易求点赞收藏~