[zz] 深入java虚拟机之本地方法

转自:http://blog.csdn.net/sunxiaosunxiao/article/details/6829899

本地方法就是直接和硬件打交道的一个软件模块,由虚拟机来执行调用。当我们的JAVA应用程序声明了本地方法就会通过虚拟就调用本地方法,本地方法中主要是实现一些对硬件的处理。

一、为什么会有本地方法呢?它的作用是什么?

java使用起来非常方便,然而有些层次的任务用java实现起来不容易,或者我们对程序的效率很在意时,问题就来了。
1>与java环境外交互:
      有时java应用需要与java外面的环境交互。这是本地方法存在的主要原因,你可以想想java需要与一些底层系统如操作系统或某些硬件交换信息时的情 况。本地方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解java应用之外的繁琐的细节。
 2>与操作系统交互:
      JVM支持着java语言本身和运行时库,它是java程序赖以生存的平台,它由一个解释器(解释字节码)和一些连接到本地代码的库组成。然而不管怎样, 它毕竟不是一个完整的系统,它经常依赖于一些底层(underneath在下面的)系统的支持。这些底层系统常常是强大的操作系统。通过使用本地方法,我 们得以用java实现了jre的与底层系统的交互,甚至JVM的一些部分就是用C写的,还有,如果我们要使用一些java语言本身没有提供封装的操作系统 的特性时,我们也需要使用本地方法。

还有其它和硬件有关的操作都是通过本地方法来实现的。

二、JVM怎样使Native Method跑起来
       我们知道,当一个类第一次被使用到时,这个类的字节码会被加载到内存,并且只会回载一次。在这个被加载的字节码的入口维持着一个该类所有方法描述符的list,这些方法描述符包含这样一些信息:方法代码存于何处,它有哪些参数,方法的描述符(public之类)等等。
      如果一个方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针。这些实现在一些DLL文件内,但是它们会被操作系统加载到java程 序的地址空间。当一个带有本地方法的类被加载时,其相关的DLL并未被加载,因此指向方法实现的指针并不会被设置。当本地方法被调用之前,这些DLL才会 被加载,这是通过调用java.system.loadLibrary()实现的

三、实现本地方法的实例(该实例我是从网上看得)

1.装入和链接本地方法

本Java程序的作用是使用一个本地方法print(),代替Java类库中的打印方法System.out.println()。

public class HelloWorld {

private native String print(String s);

public static void main(String[] args) {

String s= new String("HelloWorld");

newHelloWorld().print(s);

}

static {

System.loadLibrary("lib—native.dll ");

}

}

当Java程序运行开始时,调用Java API类库中System类的方法load()装入一个平台相关的本地库,传递给System.load的参数是一个库名,程序员可以用单个库去存储任意 数目的类所需要的本地方法。这时虚拟机内部为每个类装入器维持了一个列表,存放已经装入的本地库。如果下层的操作系统不支持动态链接,本地方法库必须预先 链接到虚拟机上。意识是说通过应用程序把本地方法的库加载到虚拟机中。

2. 编写本地方法
  先给出编写本地方法的例子:
#include <jni.h>

//该头文件是执行命令 javah HelloWord 生成的。

#include <stdio.h>
void JavaHelloWorldprint(JNIEnv *env, jobject obj, jstring jstr)
{
 char *strcopy;
 const char *strchars;
 int strlength;
 
 strchars = (*env)->GetStringUTFChars(env, jstr, NULL);
 
 strlength = (*env)->GetStringUTFLength(env, jstr) + 1;
 strcopy = (char*) malloc(strlength * sizeof(char));
 strncpy(strcopy, strchars, strlength);
 
 (*env)->ReleaseStringUTFChars(env, jstr, strchars);
 
 strcopy[strlength-1] = 0;
 printf("%s", strcpy);
 return;
}

本地方法的第一个参数是JNI 接口指针,接口指针指向一个指针数组,数组的每个元素指向一个接口函数。本地代码通过调用JNI接口函数访问Java 虚拟机的特定功能。接口指针的结构如图2所示。

第二个参数取决于此方法是静态还是非静态。非静态本地方法的第二个参数是调用本地方法Java类所属对象,静态方法的第二个参数则是调用本地方法Java类。剩下的参数(以对象形式表示)和通常的Java方法参数一致。本地方法将结果通过返回值传递给调用它的程序。

3、在动态库或静态库中解析本地方法
  动态链接器的解析完全基于本地方法的名字。本地方法的名字由下面几部分组成:
  .前缀 Java
  .类名全称
  .下划线的分隔符
  .方法名
  .为了重载本地方法(同名的本地方法但参数不同),两个 "——"后跟参数的签名。
  当虚拟机检查到Java程序中本地方法的关键字native时,立即为本地方法在本地库中检查相匹配的本地方法名。首先检查一个短名,即不带参数类型 的名字。然后检查长名(当一个本地方法重载另一个本地方法时)。如果一个本地方法和另一个非本地方法同名,是允许的。非本地方法不驻留在本地库中。
  当虚拟机到本地库中检测到相匹配的本地方法名后,随即获得与本地方法名相对应的本地函数的地址(本地方法的代码段),执行本地库中相关本地函数, 将本地函数返回值进行保存。

posted on 2012-07-04 17:46 yoyo_zeng 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/zengyou/archive/2012/07/04/2576580.html

[zz] 深入java虚拟机之本地方法相关推荐

  1. 从几个sample来学习Java堆,方法区,Java栈和本地方法栈

    2019独角兽企业重金招聘Python工程师标准>>> 最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程 ...

  2. JVM程序计数器,虚拟机栈,本地方法栈

    程序计数器 它记录了程序执行字节码的行号和指令,字节码解释器的工作就是改变程序计数器的值,切换下一条需要执行的指令(分支,循环,跳转,异常等).java虚拟机是多线程通过轮流切换CPU时间片的方式实现 ...

  3. 【Java基础】本地方法的理解(native方法)

    1.什么是本地方法? 本地方法就是java代码里面写的native方法,它没有方法体.是为了调用C/C++代码而写的.在JNI程序里面使用. 例子: 下面的代码在java中声明了一个本地方法,但是没有 ...

  4. java底层原理书籍_不愧是阿里p8大佬!终于把Java 虚拟机底层原理讲清楚了,请签收...

    概述 JVM 的内存模型和 JVM 的垃圾回收机制一直是 Java 业内从业者绕不开的话题(实际调优.面试)JVM是java中很重要的一块知识,也是面试常问的问题之一,直至今天,仍然还有许多面试者在被 ...

  5. Java虚拟机内存区域---学习笔记

    Java虚拟机 虚拟机: 定义:模拟某种计算机体系结构,执行特定指令集的软件. 种类: 系统虚拟机(Virtual Box .VMware) 进程虚拟机(JVM.Adobe Flash Player. ...

  6. 面试之什么是java虚拟机

    java虚拟机体系结构 方法区 堆 java虚拟机栈 本地方法栈 方法区 java虚拟机编译的class文件中二进制数据类型解析数据存在方法区中 是所有线程共享 和存在数据的线程安全问题 当二个线程使 ...

  7. 虚拟机 java 开发_深入浅出 Java 虚拟机 · 通往高级 Java 开发的必经之路

    第一章 JVM 内存模型 Java 虚拟机(Java Virtual Machine=JVM)的内存空间分为五个部分,分别是:程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区. 下面对这五个区域 ...

  8. Java 虚拟机 最易理解的 全面解析

    先上一个最容易理解的类实例化的内存模型案例截图: 转载自:https://www.zybuluo.com/Yano/note/321063 周志明著的<深入理解 Java 虚拟机>的干货~ ...

  9. Java虚拟机------JVM内存区域

    JVM内存区域运行时数据区域分为两种: JVM内存区域 运行时数据区域分为两种: 线程隔离的数据区: 程序计数器 Java虚拟机栈 本地方法栈 所有线程程共享的数据区: Java堆 方法区 JVM 内 ...

最新文章

  1. java datetime now_相当于C#的DateTime.Now在Java中?
  2. 前端开发进阶手册.pdf
  3. spring boot处理请求返回值的格式(自定义消息转换器)
  4. PHP,Mysql-根据一个给定经纬度的点,进行附近地点查询–合理利用算法,效率提高2125倍...
  5. 一加手机史上超大购机优惠 以旧换新至高补贴3800元
  6. 计算机技术在音乐专业中的应用与探索,计算机技术在音乐教学中的应用与研究...
  7. Linux源码包和脚本安装包的安装方法
  8. 微盾php脚本解密,微盾php解密(黑刀微盾解密专家)
  9. linux的消息队列的创建和实现
  10. 面试题——关于文本加密
  11. 数组方法的增删等19种操作:unshift 、shift,push、pop、splice等等...!
  12. SIFT算法原理(2)-极值点的精确定位
  13. Python之水仙花数问题解决
  14. html字体颜色渐变
  15. 音乐生毕业论文有什么好的选题?
  16. x86汇编_指令集大全_笔记_6
  17. Python 二维数据
  18. 实现抖音霓虹灯效果---OpenCV-Python开发指南(55)
  19. 记大学计网课设——基于B/S架构的视频点播系统设计
  20. uniapp 动态切换应用图标、名称插件(如新年、国庆等) Ba-ChangeIcon

热门文章

  1. python之dict基础类型
  2. android:showAsAction=never报错
  3. java-web——第十课 session
  4. Spring Boot 之构建Hello Word项目
  5. 数据库设计的酸(ACID)碱(BASE)原则
  6. 老李秘技:loadrunner11是否还支持dblib协议?
  7. dirname(__FILE__) 的使用总结
  8. 将VS2005中的.CS文件在网页中显示的方法
  9. 《LeetCode力扣练习》剑指 Offer 15. 二进制中1的个数 Java
  10. html页面左对齐 不换行,css如何设置不换行?