咱們都知道java虛擬機所管理的內存區域包括方法區,堆,虛擬機棧,本地方法棧,程序計數器。
在《深刻理解java虛擬機》中,周志明老師對虛擬機棧進行了講解,可是對本地方法棧卻一筆帶過。今天咱們就來對本地方法棧作下深刻......
首先咱們先回顧一下虛擬機棧。java
虛擬機棧是線程私有的,它的生命週期與線程相同。c++
虛擬機棧是java方法執行的線程內存模型:每一個java方法在執行時都會建立一個「棧幀」,棧幀的結構分爲「局部變量表,操做數棧,動態連接,方法出口」幾個部分。棧幀中的局部變量表存放着一個方法的全部局部變量。
對於java類中的方法來講:方法調用時,建立棧幀,並壓入虛擬機棧;方法執行完畢,棧幀出棧並銷燬。tcp
單個線程請求的棧深度大於虛擬機容許的深度,則會拋出StackOverflowError;
當整個虛擬機棧內存耗盡時,沒法再申請到內存會拋出OutOfMemoryError;操作系統
虛擬機棧服務於java方法,本地方法棧服務於Native方法。線程
其實Native方法是一個用native關鍵字修飾的方法,它實質上就是一個java調用其它語言的接口(像調用C,C++等)。
看到這裏想到了什麼?JNI調用的時候就是依託於Native方法。code
①儘管java很好用,可是效率上不如c和c++
②java須要和底層操做系統或者和硬件交互接口
(這並非咱們在Android開發中使用的方式,可是原理上是相同的)生命週期
public class MyNative { public static native String myPrint(); static { System.loadLibrary("print"); } public static void main(String[] args){ new MyNative().myPrint(); } }
經過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
#include 'MyNative.h' JNIEXPORT jstring JNICALL Java_MyNative_myPrint (JNIEnv *env, jclass jobj) { return env->NewStringUTF("hellonative"); }
編譯後生成dll文件開發