從本地方法棧看到jni調用


我們都知道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 <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");
}

3.5 運行,打印結果。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM