簡體   English   中英

如何避免在Java和本機C ++代碼之間復制數據

[英]How to avoid copying data between Java and Native C++ Code

我正在編寫C ++庫,該庫將由不同的Android應用程序用來處理某種組織成二維數據之類的數據,其中二維存儲沒有預定義的大小限制(例如float數組的數組,數組的大小可能會很大) )。

當前解決方案使用SWIG將數據從Java代碼分配的內存復制到C ++結構。 事實證明,每個float值數組(在Java中)成為float(在C ++中)的向量。

問題在於,大量數據的復制會增加耗盡應用程序可用內存的風險。 我知道,無論如何,應該通過輸入量限制來解決內存消耗問題,但是該庫不知道有多少可用內存,並且應該具有整個數據(需要重復訪問任何數據元素)才能執行正確的處理。

因此,現在我正在考慮將一個數據存儲用於Java和C ++的可能性,因此C ++代碼要求直接將Java代碼存儲的數據訪問Java端分配的內存(不考慮將C ++代碼分配的內存視為單個存儲)。

我想知道如何以安全的方式組織這種內存共享(最好使用SWIG)。

我覺得這樣的實現可能會遇到一些困難,例如,使用Java垃圾收集器(C ++代碼可以尋址已釋放的存儲)並通過包裝器減慢內存訪問的速度(如前所述,該庫要求重復訪問每個數據項)…但是也許有人建議我一個可靠的解決方案。 如果有足夠的和令人信服的論據支持,我的想法為什么是錯誤的解釋也可以接受。

您可以使用Critical Native實現訪問原始數據數組。 這種技術可以直接訪問jvm內存,而不會在Java和本機代碼之間傳輸數據帶來麻煩。

但這有下一個限制

  • 必須是靜態的並且不同步;
  • 參數類型必須是原始或原始數組;
  • 實現不得調用JNI函數,即,它不能分配Java對象或引發異常。
  • 不應長時間運行,因為它將在運行時阻止GC。

關鍵本機的聲明類似於常規的JNI方法,除了:

  • 它以JavaCritical_而不是Java_
  • 它沒有額外的JNIEnv*jclass參數;
  • Java數組通過兩個參數傳遞:第一個是數組長度,第二個是指向原始數組數據的指針。 也就是說,無需調用GetArrayElements和朋友,您可以立即使用直接數組指針。

請查看原始答案源文章以獲取詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM