亲宝软件园·资讯

展开

从本地方法栈看到jni调用

六式 人气:1
我们都知道java虚拟机所管理的内存区域包括方法区,堆,虚拟机栈,本地方法栈,程序计数器。 在《深入理解java虚拟机》中,周志明老师对虚拟机栈进行了讲解,但是对本地方法栈却一笔带过。今天我们就来对本地方法栈做下深入...... 首先我们先回顾一下虚拟机栈。 ###1.虚拟机栈 ####1.1虚拟机栈的特点 虚拟机栈是线程私有的,它的生命周期与线程相同。 ####1.2虚拟机栈的概念 虚拟机栈是java方法执行的线程内存模型:每个java方法在执行时都会创建一个“栈帧”,栈帧的结构分为“局部变量表,操作数栈,动态链接,方法出口”几个部分。栈帧中的局部变量表存放着一个方法的所有局部变量。 对于java类中的方法来说:方法调用时,创建栈帧,并压入虚拟机栈;方法执行完毕,栈帧出栈并销毁。 ####1.3关于虚拟机栈的异常 单个线程请求的栈深度大于虚拟机允许的深度,则会抛出StackOverflowError; 当整个虚拟机栈内存耗尽时,无法再申请到内存会抛出OutOfMemoryError; ###2.本地方法栈 虚拟机栈服务于java方法,本地方法栈服务于Native方法。 ####2.1那么何为Native方法? 其实Native方法是一个用native关键字修饰的方法,它实质上就是一个java调用其它语言的接口(像调用C,C++等)。 看到这里想到了什么?JNI调用的时候就是依托于Native方法。 ####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 /* 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文件,打印结果。

加载全部内容

相关教程
猜你喜欢
用户评论