从本地方法栈看到jni调用

咱们都知道java虚拟机所管理的内存区域包括方法区,堆,虚拟机栈,本地方法栈,程序计数器。
在《深刻理解java虚拟机》中,周志明老师对虚拟机栈进行了讲解,可是对本地方法栈却一笔带过。今天咱们就来对本地方法栈作下深刻......
首先咱们先回顾一下虚拟机栈。java

1.虚拟机栈

1.1虚拟机栈的特色

虚拟机栈是线程私有的,它的生命周期与线程相同。c++

1.2虚拟机栈的概念

虚拟机栈是java方法执行的线程内存模型:每一个java方法在执行时都会建立一个“栈帧”,栈帧的结构分为“局部变量表,操做数栈,动态连接,方法出口”几个部分。栈帧中的局部变量表存放着一个方法的全部局部变量。
对于java类中的方法来讲:方法调用时,建立栈帧,并压入虚拟机栈;方法执行完毕,栈帧出栈并销毁。tcp

1.3关于虚拟机栈的异常

单个线程请求的栈深度大于虚拟机容许的深度,则会抛出StackOverflowError;
当整个虚拟机栈内存耗尽时,没法再申请到内存会抛出OutOfMemoryError;操作系统

2.本地方法栈

虚拟机栈服务于java方法,本地方法栈服务于Native方法。线程

2.1那么何为Native方法?

其实Native方法是一个用native关键字修饰的方法,它实质上就是一个java调用其它语言的接口(像调用C,C++等)。
看到这里想到了什么?JNI调用的时候就是依托于Native方法。code

2.2为何会有native方法

①尽管java很好用,可是效率上不如c和c++
②java须要和底层操做系统或者和硬件交互接口

3.用native的方式实现jni

(这并非咱们在Android开发中使用的方式,可是原理上是相同的)生命周期

3.1 编写咱们的Native方法,建立MyNative.java文件

public class MyNative {
	public static native String myPrint();
	static {
		System.loadLibrary("print");
	}
	public static void main(String[] args){
	new MyNative().myPrint();
	}
	
}

3.2 编译.java文件,生成字节码文件

3.3 获取.h文件

经过javah -jni MyNative就会产生一个MyNative.h文件。内存

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class MyNative */

#ifndef _Included_MyNative
#define _Included_MyNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     MyNative
 * Method:    myPrint
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MyNative_myPrint
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

3.4编写print.cpp文件

#include 'MyNative.h'
JNIEXPORT jstring JNICALL Java_MyNative_myPrint
  (JNIEnv *env, jclass jobj)
{	return env->NewStringUTF("hellonative");
}

编译后生成dll文件开发

3.5 运行MyNative文件,打印结果。

相关文章
相关标签/搜索