JVM运行时数据区——本地方法接口和本地方法栈

news2024/11/15 11:40:40

1、本地方法接口

虽然Java语言使用非常广泛,但是有些事务Java仍然无法处理。例如线程相关的功能,在线程类当中就有很多本地方法接口。那么Java如何来处理这些问题呢?Java设计师提出了一种解决方案就是本地方法接口。本贴将会讲解本地方法接口在Java语言中所起到的作用,以及为什么要使用本地方法接口。

1.1、本地方法接口概述

本地方法接口(Java Native Interface,JNI)在JVM中的位置,如下图所示:
在这里插入图片描述
图中的虚线框区域就是本地方法接口,负责和本地方法库、JVM之间的交互。

官方这样描述本地方法:“A method that is native and implemented in platform-dependent code,typically written in another programming language such as C.”意思是本地方法的实现一般是由其他语言编写的,比如可以使用C语言实现。我们可以理解为JNI就是使用Java语言调用非Java代码实现的接口。

JNI可以帮助Java代码与使用其他编程语言(例如C、C++和汇编)编写的应用程序和库进行交互。这个特征并非Java所特有,许多编程语言都有这一机制,比如在C++中,可以用extern '‘C’'告知C++编译器去调用一个C语言的函数。在定义一个Native Method时,并不提供实现体(类似只定义了Java Interface),因为其实现体是由非Java语言在外面实现的。

JNI最重要的好处是它对底层JVM的实现没有任何限制。因此,JVM供应商可以添加对JNI的支持,而不会影响JVM的其他部分。

本地方法接口的作用是融合不同的编程语言为Java所用,它的初衷是融合C/C++程序。例如Object类的getClass()方法,它是有方法体的,不过方法体的具体实现并不是Java语言实现的,主要是C/C++语言实现的,如下图所示:
在这里插入图片描述
如下代码清单所示,演示了本地方法的格式:
在这里插入图片描述
由上述代码示例可知,每个方法都是用native修饰,并且都没有方法体(具体的方法体由非Java代码实现),表示该方法为本地方法。需要注意的是该方法并不是抽象方法。标识符native可以与所有其他的Java标识符连用,但是abstract除外。

上面介绍了什么是Native Method,但是为什么要使用Native Method呢?下面将会从三个方面介绍Java中为什么使用Native Method。

(1)减少重复劳动。有时Java应用需要与Java外面的环境交互,这是本地方法存在的主要原因。如果本地已经有一个用另一种语言编写的库,这时候希望通过某种方式使其可供Java代码访问,而不是重新使用Java语言编写一套功能一样的库,那么这种方式就是JNI。例如,Java需要与一些底层系统交互时,本地方法为我们提供了一个非常简洁的接口,而且我们无须去了解Java应用之外的烦琐的细节。要不然底层系统的厂商还需要提供一套Java形式的类库,这样就是重复劳动了。

(2)标准Java类库不支持应用程序所需的平台相关特性。JVM支持Java语言本身和运行时库,它是Java程序赖以生存的平台,它由一个解释器(解释字节码)和一些连接到本地代码的库组成。然而不管怎样,它毕竟不是一个完整的系统,它经常依赖一些底层系统的支持,这些底层系统常常是强大的操作系统。通过本地方法,我们可以使用Java自身的JRE与底层系统进行交互,甚至JVM的部分实现就是用C语言编写的。还有,如果我们要使用一些Java语言本身没有提供封装的操作系统的特性时,也需要使用本地方法。

(3)性能要求。假如想用较低级别的语言(例如汇编)实现一小部分性能要求严格的代码,这时候就可以使用到JNI了。目前本地方法的使用越来越少,在企业级应用中已经比较罕见,除非是与硬件有关的应用,比如通过Java程序驱动打印机或者Java系统管理生产设备。因为现在的异构领域间的通信很发达,比如可以使用Socket通信,也可以使用Web Service,等等。

1.2、小结

我们可以看出Java语言中的部分方法并非由Java实现,这类方法的存在使Java与外界环境的交互更加方便快捷。Java为我们提供的简洁的本地方法接口,不仅使我们无须去了解Java应用之外的烦琐细节,还增加了Java语言的扩展性。

2、本地方法栈

重点讲解运行时数据区中的本地方法栈区域,包括本地方法栈的概念,以及本地方法栈中可能发生的异常情况。

2.1、本地方法栈概述

Java虚拟机实现可能会使用到传统的栈(通常称为C Stack)来支持本地方法(使用Java语言以外的其他语言编写的方法)的执行,这个栈就是本地方法栈(Native Method Stack)。

本地方法栈和Java虚拟机栈发挥的作用是类似的,它们直接的区别是Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用,如下图所示:
在这里插入图片描述
本地方法栈是线程私有的。本地方法栈的大小允许被实现成固定大小的或者是可动态扩展的。在内存溢出方面,它与Java虚拟机栈也是相同的。

如果线程请求分配的栈容量超过本地方法栈允许的最大容量,Java虚拟机将会抛出一个StackOverflowError异常。

如果本地方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,那么Java虚拟机将会抛出一个OutOfMemoryError异常。

它的具体做法是在Native Method Stack中登记本地方法,在Execution Engine执行时加载本地方法库。

当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。它和虚拟机拥有同样的权限,如下3项表示本地方法可能涉及的权限调用:

  • 本地方法可以通过本地方法接口来访问运行时数据区中的其他区域。
  • 本地方法甚至可以直接使用本地处理器中的寄存器。
  • 本地方法可以直接从本地内存的堆中分配任意数量的内存。

并不是所有的JVM都支持本地方法,因为Java虚拟机规范并没有明确要求本地方法栈的使用语言、具体实现方式、数据结构等。如果JVM产品不打算支持本地方法,也可以无须实现本地方法栈,如果支持本地方法栈,那这个栈一般会在线程创建的时候按线程分配。

在Java中,本地方法栈和虚拟机栈是如何关联的呢?如下图所示:
在这里插入图片描述
当调用线程的start()方法的时候,在当前线程中开辟一个start()方法的栈帧并压入栈,在start()方法中又调用了start0()方法(图中画框处)。start0()方法是一个本地方法,所以start0()方法需要通过本地方法栈调用,可以使用动态链接的方式直接指向本地方法,由执行引擎来执行该本地方法。类似的案例还有Java应用中连接MySQL数据库或者Redis数据库等。

2.2、小结

本地方法栈用于管理本地方法的调用,但是本地方法依赖JVM的实现,有的JVM并不支持本地方法,HotSpot虚拟机是支持的。Java虚拟机规范允许本地方法栈实现成固定的大小,或者根据计算来实现动态扩展和收缩。本地方法栈可能会发生StackOverflowError和OutOfMemoryError异常情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1481984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spark sql 转换字符串数组成多列结构

背景 在平时使用spark sql分析数据时,特别是分析从mysql的表入仓的hive表时,我们会经常和字符串数组的列打交道,而且这种情况下我们一般都需要把一行字符串数组的行数据转成多列的形式,我们看下怎么写这个sql spark sql 转换字符…

idea中maven配置(一次成功,全部细节都有)

写这篇文章的原因是maven的配置很简单,但是也很容易出错,我连配了两台电脑的maven出现了各种小错误,参考了以下两篇博文IDEA配置Maven教程(超详细版~)_idea maven配置教程-CSDN博客 一次包会——最新IDEA配置Maven指南&#xff0…

(学习日记)2024.03.01:UCOSIII第三节

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

ABAP - OOALV 单元格 F4实现

方式一:使用标准数据表,FIELDCAT字段设置值 gs_fieldcat-ref_table X. "列可编辑gs_fieldcat-ref_table MARA. "F4 参考表gs_fieldcat-ref_field MATNR. "F4 参考字段 方式二.使用自定义数据 ,实现效果如下图…

git根据文件改动将文件自动添加到缓冲区

你需要修改以下脚本中的 use_cca: false 部分 #!/bin/bash# 获取所有已修改但未暂存的文件 files$(git diff --name-only)for file in $files; do# 检查文件中是否存在"use_cca: false"if grep -q "use_cca: false" "$file"; thenecho "Ad…

【ue5】滑铲系统蓝图笔记

大致逻辑如下: 一、导入动画 滑铲蹲待机蹲行走 导入到文件夹中 可以右键设置颜色,便于区分。 二、调整动画 1.启动根运动 启动根运动后,人物才可以位移,不然只能在原地。 打开动画序列,勾选启用根运动Enabled…

【排序算法】基数排序

一:基本概念 1.1 基数排序(桶排序)介绍 基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是…

Python读取hbase数据库

1. hbase连接 首先用hbase shell 命令来进入到hbase数据库,然后用list命令来查看hbase下所有表,以其中表“DB_level0”为例,可以看到库名“baotouyiqi”是拼接的,python代码访问时先连接: def hbase_connection(hbase…

如何开好一家汽车美容店,汽车美容保养与装饰教学

一、教程描述 本套教程共由17张VCD组合而成,教程内容主要包括:美容店的设立和管理,汽车系统与内部结构,汽车美容工具与美容设备,美容用品的选择与使用,车身打蜡镀膜与内外清洁,车身抛光与漆面处…

Verilog(未完待续)

Verilog教程 这个教程写的很好,可以多看看。本篇还没整理完。 一、Verilog简介 什么是FPGA?一种可通过编程来修改其逻辑功能的数字集成电路(芯片) 与单片机的区别?对单片机编程并不改变其地电路的内部结构&#xff0…

【框架】Spring 框架重点解析

Spring 框架重点解析 1. Spring 框架中的单例 bean 是线程安全的吗? 不是线程安全的 Spring 框架中有一个 Scope 注解,默认的值是 singleton,即单例的;因为一般在 Spring 的 bean 对象都是无状态的(在生命周期中不被…

vue3 + vite 项目可以使用纯Js开发吗?

答案:可以 创建项目: 按照链接参考或者按官方: webstorm 创建vue3 vite 项目-CSDN博客 项目目录 tsconfig.json 配置允许js allowJs指定是否编译js文件,在任意文件当中,如果我们模块使用js写的,那么我们需要 将all…

微软为金融界带来革命性突破——推出Microsoft 365中的下一代AI助手:Microsoft Copilot for Finance

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

【leetcode】相交链表

大家好,我是苏貝,本篇博客带大家刷题,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 点击查看题目 思路: struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *he…

数据分析之Logistic回归分析(二元逻辑回归、多元有序逻辑回归、多元无序逻辑回归)

1、Logistic回归分类 在研究X对于Y的影响时: 如果Y为定量数据,那么使用多元线性回归分析;如果Y为定类数据,那么使用Logistic回归分析。 结合实际情况,可以将Logistic回归分析分为3类: 二元Logistic回归…

今年国内石油需求稳中有升,巡检机器人助力石油行业可持续发展

前言:全球能源市场出现普遍回落趋势,其中石油价格下降近20%,而天然气和煤炭价格更是下跌超过50%。此外,碳酸锂和光伏组件价格也纷纷下降超过50%。这种价格下滑对于全球经济的持续增长,尤其是控制通货膨胀方面&#xff…

CSS 盒子模型(box model)

概念 所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:外边距(margin),边框(border),内边距(pad…

高比例清洁能源接入下计及需求响应的配电网重构(matlab代码)

目录 1 主要内容 目标函数 重要约束条件 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现《高比例清洁能源接入下计及需求响应的配电网重构》,以考虑网损成本、弃风弃光成本和开关操作惩罚成本的综合成本最小为目标,针对配电网重构模型的…

mac 本地使用dockerfile启动 springboot项目

1.创建Dockerfile放在项目的根目录下 2.编写Dockerfile FROM openjdk:11 MAINTAINER ChengLinADD target/JiaLi-0.0.1-SNAPSHOT.jar /app.jar# 暴露 Spring Boot 应用的端口号 EXPOSE 8088 # 启动 Spring Boot 应用 CMD ["java", "-jar", "app.jar&q…

1_SQL

文章目录 前端复习SQL数据库的分类关系型数据库非关系型数据库(NoSQL) 数据库的构成软件架构MySQL内部数据组织方式 SQL语言登录数据库数据库操作查看库创建库删除库修改库 数据库中表的操作选择数据库创建表删除表查看表修改表 数据库中数据的操作添加数…