2015-12-09 63 views
0

我正在寫一個函數,它首先創建一個新的jbyteArray,如果其他所有工作都會返回。如果一切都不成功,它將返回NULL。我需要顯式配置jbyteArray嗎?

但是,如果該功能期間我已經成功地稱爲NewByteArray()後某處發生錯誤,所以我需要明確處置的jbyteArray的返回之前,或者可以,我只是把它留給垃圾收集器?

在一個粗略的草圖代碼:

jbyteArray makeAndFill(JNIEnv *env) 
{ 
    jbyteArray ba = NULL ; 

    ba = (*env)->NewByteArray(env, 1000) ; 

    if(ba == NULL) 
    return NULL ; 

    /* so far so good/

    if(fillme(ba)) 
    { 
    /* Whoops, a problem ... 
    * 
    * DO I need to free the jbyteArray explicitly before 
    * returning NULL ? 
    */ 

    return NULL ; 
    } 

    /* everything was fine 
    */ 

    return ba ; 
} 

你可以假設fillme()做所有需要的獲取和釋放代碼,只是返回FALSE如果SOEM某些原因出現了問題。如果fillme()不能完成它的工作,我們只需要該函數返回一個NULL。

我的理解是,如果我不從JNI返回jbyteArray到JAVA「適當」,它將簡單地被垃圾收集。那是對的嗎 ?

回答

2

如果這是通過Java本地方法調用的函數,那麼運行時將爲您處理本地引用。從文檔:「本地引用在本地方法調用期間有效,並在本地方法返回後自動釋放。」一旦本地引用被釋放並且沒有任何其他引用(將對象返回給Java創建一個新引用),該對象就有資格進行垃圾回收。

例外情況是,如果你有很多這樣的參考。虛擬機可以處理多少個本地引用是有限制的,但是如果你保持低於這個水平,那你就很好。

如果這在使用JNI_CreateJavaVM()創建虛擬機的非Java進程的函數中必須顯式刪除在Java本地方法調用之外創建的每個引用。在本地方法調用中,VM爲本地方法返回時破壞的引用創建一個空間。當您通過JNI_CreateJavaVM()AttachCurrentThread()GetEnv()獲得env指針時,虛擬機將不會管理爲您創建的env引用。

多一個編輯:看起來好像DetachCurrentThread()已被視爲釋放本地引用。不過,我很確定,我已經閱讀過有關問題的地方。也許它是依賴於實現的,也許報告的問題是由於錯誤造成的。該文件沒有確切地說,所以我寧願不依靠它。

+0

你能解釋爲什麼你認爲來自Java的本地調用與JNI_CreateJavaVM不一樣嗎?我早在我的C應用程序中創建了一個虛擬機,但* *在一個類中調用了Java方法,並且在那裏調用了本地方法。我沒有看到這與通過java命令啓動Java類有什麼不同,因爲這仍然涉及到創建VM。 – StephenG

+1

我編輯了文字,試圖澄清。 Java進程中的本地方法調用與非Java進程中的本地方法調用沒有區別。使用「自己的」env指針創建的引用是不同的。 – user2543253

+0

感謝您的額外細節。我會仔細研究一下。 – StephenG