1. 程式人生 > >jni未釋放資源問題。Failed adding to JNI local ref table (has 512 entries)

jni未釋放資源問題。Failed adding to JNI local ref table (has 512 entries)

基於 Android NDK 的學習之旅-----資源釋放

        做上一個專案的時候因為與C引擎互動頻繁,有時候會突然莫名其妙的的整個應用程式直接掛掉。因為我是學Java 開始的,所以對主動釋放記憶體沒多大概念(GC直接幫忙回收),後查詢原因才知道是因為JNI 有些物件記憶體未釋放引起。下面介紹下相關的資源釋放。

JNI 程式設計實現了 native code  Java 程式的互動,因此 JNI 程式碼程式設計既遵循 native code 程式語言的程式設計規則,同時也遵守 JNI 程式設計的文件規範。在記憶體管理方面,native code 程式語言本身的記憶體管理機制依然要遵循,同時也要考慮

 JNI 程式設計的記憶體管理。

本章簡單概括 JNI 程式設計中顯而易見的記憶體洩漏。從 native code 程式語言自身的記憶體管理,和 JNI 規範附加的記憶體管理兩方面進行闡述。

Native Code 本身的記憶體洩漏

JNI 程式設計首先是一門具體的程式語言,或者 C 語言,或者 C++,或者彙編,或者其它 native 的程式語言。每門程式語言環境都實現了自身的記憶體管理機制。因此,JNI 程式開發者要遵循 native 語言本身的記憶體管理機制,避免造成記憶體洩漏。以 C 語言為例,當用 malloc()在程序堆中動態分配記憶體時,JNI 程式在使用完後,應當呼叫 free() 

將記憶體釋放。總之,所有在 native 語言程式設計中應當注意的記憶體洩漏規則,在 JNI 程式設計中依然適應。

Native 語言本身引入的記憶體洩漏會造成 native memory 的記憶體,嚴重情況下會造成 native memory  out of memory

Global Reference 引入的記憶體洩漏

JNI 程式設計還要同時遵循 JNI 的規範標準,JVM 附加了 JNI 程式設計特有的記憶體管理機制。

JNI 中的 Local Reference 只在 native method 執行時存在,當 native method 執行完後自動失效。這種自動失效,使得對

 Local Reference的使用相對簡單,native method 執行完後,它們所引用的 Java 物件的 reference count 會相應減 1。不會造成 Java Heap  Java 物件的記憶體洩漏。

 Global Reference  Java 物件的引用一直有效,因此它們引用的 Java 物件會一直存在 Java Heap 中。程式設計師在使用 Global Reference時,需要仔細維護對 Global Reference 的使用。如果一定要使用 Global Reference,務必確保在不用的時候刪除。就像在 C 語言中,呼叫malloc() 動態分配一塊記憶體之後,呼叫 free() 釋放一樣。否則,Global Reference 引用的 Java 物件將永遠停留在 Java Heap 中,造成Java Heap 的記憶體洩漏。

1、什麼需要釋放? 

什麼需要什麼呢 ? JNI 基本資料型別是不需要釋放的 , 如 jint , jlong , jchar 等等 。 我們需要釋放是引用資料型別,當然也包括陣列家族。如:jstring ,jobject ,jobjectArray,jintArray 等等。

當然,大家可能經常忽略掉的是 jclass ,jmethodID , 這些也是需要釋放的哦

2、如何去釋放?

1)      釋放String

jstring jstr = NULL;

char* cstr = NULL;

//呼叫方法

jstr = (*jniEnv)->CallObjectMethod(jniEnv, mPerson, getName);

cstr = (char*) (*jniEnv)->GetStringUTFChars(jniEnv,jstr, 0);

__android_log_print(ANDROID_LOG_INFO, "JNIMsg", "getName  ---- >  %s",cstr );

//釋放資源

(*jniEnv)->ReleaseStringUTFChars(jniEnv, jstr, cstr);

(*jniEnv)->DeleteLocalRef(jniEnv, jstr);

2)      釋放 類 、物件、方法

(*jniEnv)->DeleteLocalRef(jniEnv, XXX);

“XXX” 代表引用物件

3)      釋放 陣列家族

jobjectArray arrays = NULL;

jclass jclsStr = NULL;

jclsStr = (*jniEnv)->FindClass(jniEnv, "java/lang/String");

arrays = (*jniEnv)->NewObjectArray(jniEnv, len, jclsStr, 0);

(*jniEnv)->DeleteLocalRef(jniEnv, jclsStr);  //釋放String類

(*jniEnv)->DeleteLocalRef(jniEnv, arrays); //釋放jobjectArray陣列

native method 呼叫 DeleteLocalRef() 釋放某個 JNI Local Reference 時,首先通過指標 p 定位相應的 Local Reference 在 Local Ref 表中的位置,然後從 Local Ref 表中刪除該 Local Reference,也就取消了對相應 Java 物件的引用(Ref count 減 1)。

相關推薦

jni釋放資源問題Failed adding to JNI local ref table (has 512 entries)

基於 Android NDK 的學習之旅-----資源釋放         做上一個專案的時候因為與C引擎互動頻繁,有時候會突然莫名其妙的的整個應用程式直接掛掉。因為我是學Java 開始的,所以對主動釋放記憶體沒多大概念(GC直接幫忙回收),後查詢原因才知道是因為JNI

Jni 記憶體洩露(Failed adding to JNI pinned array ref table (1024 entries))

問題重現 錯誤程式碼 解決辦法 原因 問題重現 Failed adding to JNI pinned array ref table (1024 entries) 在開發藍芽模組升級的時候, 由於要傳送

ADO.net應該手動釋放資源

本來對於C#的GC有諸多爭議,像我這樣從偽C++程式設計師轉過來的,自然對於靠第三方回收堆上物件的行為,感到一種恐懼和無力。但是,既然Java和C#都有GC,總還認為是可靠的,但是,誰知道這個可靠的GC缺出問題了。 案例:同事做的一個操作資料庫的B/S小程式出問題了,前臺a

wpf圖片輪播(釋放資源

今天有個臨時需求,做圖片輪播,以前做了一個,找不到了。 想了個簡單的方法臨時拿著用,這裡先記著有空再來改。 上程式碼-----》 using System; using System.IO; using System.Windows; using System.Windo

linux 查詢被刪除但是釋放空間的檔案 並釋放資源

檢視已刪除但是未釋放空間的檔案:lsof | grep deleted 刪除已刪除但是未釋放空間的檔案:lsof | grep deleted | awk '{print $2}' | xargs -I

使用HttpURLConnection時遇到的資源釋放的問題

今天自己寫了一個壓力測試的小程式,同時啟100個執行緒,每個執行緒都序列地訪問應用伺服器上的一個jsp頁面200次。在程式運行了一會兒以後,問題來了:java.net.SocketException: No buffer space available (maximum

[BUG]ASP.NET 被授權訪問所請求的資源請考慮授予 ASP.NET 請求標識訪問此資源的許可權

“/”應用程式中的伺服器錯誤。-------------------------------------------------------------------------------- 對路徑“//10.6.27.8/rec/rec/20100719/170007.vo

文本情感分析的基礎在於自然語言處理、情感詞典、機器學習方法等內容以下是我總結的一些資源

建議 中心 這場 分詞 自然語言處理 目前 能力開放 計算 推薦算法 文本情感分析的基礎在於自然語言處理、情感詞典、機器學習方法等內容。以下是我總結的一些資源。 詞典資源:SentiWordNet《知網》中文版中文情感極性詞典 NTUSD情感詞匯本體下載 自然語言處理

spring boot 靜態資源

web資源 length fix 入口 cep 等等 comm esp reat spring Boot 默認為我們提供了靜態資源處理,使用 WebMvcAutoConfiguration 中的配置各種屬性。 建議大家使用Spring Boot的默認配置方式,如果需要特殊處

如何恢復釋放租約的HDFS文件

too cat converter lean amr table response mean mis 之前有文章介紹過HDFS租約帶來的問題,導致spark應用無法正常讀取文件,只能將異常文件找出並且刪除後,任務才能繼續執行。 但是刪除文件實在是下下策,而且文件本身其實並未

釋放資源

statement 記錄 關閉 try final stat tro 關閉連接 con Jdbc程序運行完後,切記要釋放程序在運行過程中,創建的那些與數據庫進行交互的對象,這些對象通常是ResultSet, Statement和Connection對象,特別是Connect

Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage failed: Unable to find main class

spl final package exce main project clas ini exit 異常 [INFO] --- spring-boot-maven-plugin:1.5.6.RELEASE:repackage (default) @ spring-boot

【轉】編寫高質量代碼改善C#程序的157個建議——建議46:顯式釋放資源需繼承接口IDisposable

cep nag pre 回收 如果 win name 實現 每一個 建議46:顯式釋放資源需繼承接口IDisposable C#中的每一個類型都代表一種資源,資源分為兩類: 托管資源:由CLR管理分配和釋放的資源,即從CLR裏new出來的對象。 非托管資源:不受CLR管

一個監控釋放已刪除文件空間的腳本

字符串 最終 in use usr cat 白名單 pytho system 存儲空間 具體需求: 1、 需要分析出是視頻/data分區個類文件占比(實際文件占比多少,一般實際文件小於占比70%以下大多為已刪除文件單未釋放磁盤空間)。 2、 需要統計已刪除文件但未釋放空間的

Handshake failed due to invalid Upgrade header: null 解決方案

led ade cal lis ex18 解決 代碼 number border 解決方案,在 Nginx ,location 中添加以下紅色代碼: proxy_set_header Upgrade $http_upgrade; proxy_set_header C

使用代碼來加載資源釋放資源

ogr 腳本 ogre 去掉 callback arr array color prefab 資源不只是可以通過編輯器綁定獲取.其實他還可以使用代碼來動態加載.cc.loader1.它有3個默認的Pipeline(管道):(1)assetLoader:主要用於加載資源,加載

UWP DEP0700: 應用程序註冊失敗[0x80073CF9] 另一個用戶已安裝此應用的打包版本當前用戶無法將該版本替換為打包版本

.cn 打包 ive 另一個 pan package 用戶 AC size 原文:UWP DEP0700: 應用程序註冊失敗。[0x80073CF9] 另一個用戶已安裝此應用的未打包版本。當前用戶無法將該版本替換為打包版本。最近電腦抽風,我在【應用程序和功能】中重置了以下我

Context []startup failed due to previous errors 問題解決

信息 log4j bug sse err led jar logger debug log4j.rootLogger=info,Console,R log4j.appender.Console=org.apache.log4j.ConsoleAppender

curl: (7) Failed connect to 172.16.100.199:9200; 沒有到主機的路由

ble stat ber ret iptable stop int iter OS 沒有到主機的路由這種問題很常見,多數是由機器的防火墻沒有關閉。 Ubuntu 查看防火墻狀態 ufw status 關閉防火墻 ufw disable centos6 查看防火墻狀

關於mysql 刪除數據後(.MYD,MYI)物理空間釋放

使用 表優化 數據 lob 大量 cal 定期 blob 特定 關於mysql 刪除數據後物理空間未釋放 OPTIMIZE TABLE 當您的庫中刪除了大量的數據後,您可能會發現數據文件尺寸並沒有減小。這是因為刪除操作後在數據文件中留下碎片所致。OPTIMIZE TABLE