我正在使用一个包含带有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