我正在使用一個包含帶有Fortran調用的本機庫的舊Java程序。使用本機代碼的java內存泄漏
所以,我有Java通過JNI調用C,然後調用Fortran。
在生產中,我們有一個出像存儲器錯誤的:
本機的存儲器分配(malloc的)未能分配用於jfloat 120000個字節在C:\ BUILD_AREA \ jdk6_37 \熱點\ SRC \共享\ VM \ prims \ jni.cpp
我懷疑這是內存泄漏。
我是新來的公司,我想在linux上工作,但他們讓我在Windows上工作:( 正在生產中我們使用.so文件,因爲我們在solaris上,而我在Windows上使用DLL (邏輯)
首先,我嘗試重現生產問題,於是我創建了一個加載DLL的單元測試,並調用多次調用本地方法的java類 當我這樣做時,我看到用processExplorer.exe表示內存每2秒增長到2MB,而且我有例外,就像在製作中那樣。
我很高興我成功地轉載了這個問題,我可以說th問題來自C或Fortran代碼。
接下來,我試圖刪除調用Fortran和我的Java只叫C(無Fortran語言,這個測試允許我看看問題是否是從C或Fortran的到來。)
,結果是記憶沒有動!涼!我可以說我在C中沒有任何malloc/free的問題。
所以,我決定學習一點Fortran以查看代碼。 :)
我瞭解到,在Fortran中,我們可以使用allocate和deallocate關鍵字來播放內存。而我的代碼不包含這些關鍵字。 :(
這一切後,有人給我在Solaris上獲得啓動我的JUnit測試調用Java的> JNI-> C => Fortran和使用。所以,而不是DLL的。
和驚喜 - 內存沒有移動!!!我在Solaris或RedHat下沒有任何問題
我被卡住了,因爲生產中存在問題,但我無法清楚地重現它。:(
爲什麼我會看到DLL和SO之間的區別?代碼(java/C/Fortran)是完全一樣的,因爲它是我編譯它的。
我該如何調查更多?
我試圖做一個內存轉儲下的窗口,我重現了這個問題,但我什麼也沒看到。
在jvm中是否存在問題?或者問題可以在通過JNI傳遞給C的對象中?
非常感謝您幫助我解決這個問題。
信息:我使用Windows 7 64位
PS:我是法國人,所以請原諒我的英語。我盡力每次都盡力而爲。 )
這裏是報頭F的C代碼:
JNIEXPORT jint JNICALL Java_TrtModlin_modlin_1OM
(JNIEnv * env, jobject obj,
jfloatArray pmtPar,
jobjectArray abaquePar, jobjectArray donPar, jfloatArray condPar, jobjectArray resPar, jintArray flagPar)
{
一些代碼,並且該方法調用對的Fortran
#ifndef unix
modlin_OM(pmt, abaque, don, cond, res, & iFlag) ;
#else
modlin_om_(pmt, abaque, don, cond, res, & iFlag) ;
#endif
:
#ifndef unix
__MINGW_IMPORT void modlin_OM(float pmt[], float abaque[][], float don[][], float cond[], float res[][], int flag[]) ;
#else
extern void modlin_om_(float * pmt, float * abaque, float * don, float * cond, float * res, int * flag) ;
#endif
,並且該方法後
正如我之前所說,我通過刪除這些行來測試對C的調用,並且t他的記憶力沒有增長:(我測試通過刪除一行免費(someVar)和內存增長,因爲免費在這種情況下沒有完成。這就是爲什麼我得出結論說我的C和Free/Malloc一致。
你是否有這兩種平臺(Unix和Windows)的C綁定的來源? – fge
是的,我有源,但它是相同的Windows或UNIX,我在我的問題結束時添加它(如果你想所有的來源,我可以給你,如果你想) –
哪個fortran編譯器?我們使用的是 – Peter