即使重新加载库,JNA也会保持状态

时间:2020-03-19 15:17:05

标签: fortran jna

我有一个Fortran代码,我尝试将其包装为Java / Scala代码。我的问题是,即使我将库放在两个调用之间,fortran中变量的状态仍会保留:

Fortran代码:

let foo1 = moment(activeToDateTimeString).utcOffset(-4, true);

以及Java / Scala代码:

  subroutine mySub()
  implicit none  

  DOUBLE PRECISION x
  COMMON/myCommon/ x

  print*,x
  x = 99.99

  end subroutine mySub

打印到控制台:

trait FortranLibrary extends Library {
 // native symbols
 def mysub_() 
}

def main(args: Array[String]): Unit = {

 var INSTANCE: FortranLibrary = Native.synchronizedLibrary(
  Native.load("sub.so", classOf[FortranLibrary])
 ).asInstanceOf[FortranLibrary]
 // call native subroutine
 INSTANCE.mysub_()

 println("------SECOND CALL-----")

 // clean library, reload
 INSTANCE = null
 System.gc()
 // make new instance
 INSTANCE = Native.synchronizedLibrary(
  Native.load(libpath, classOf[FortranLibrary])
 ).asInstanceOf[FortranLibrary]
 // call native subroutine
 INSTANCE.mysub_()
}

因此即使How to dispose library loaded with JNA中提议的库被处置了,第二次调用中仍然存在先前设置的x = 99.99,如何避免这种情况?

编辑:我正在使用 0.000000000000000E+000 ------SECOND CALL----- 99.9899978637695 的intel fortran编译器,因此变量应使用0重新初始化

1 个答案:

答案 0 :(得分:0)

在后台,JNA在加载NativeLibrary对象后会保留对其的引用,除非明确调用dispose(),否则它不会释放它。

dispose()方法包含在对象的finalize()中,该方法将在垃圾回收时被调用,但是,不能始终执行它。在您发布的代码段中,您将引用设为空,并使用了一个System.gc()调用,这只是释放对象的建议。在您尝试过的注释中指出的一个更好的选择是您自己致电dispose()disposeAll()

但是,正如my answer to your linked question中所指出的那样,需要很小的时间延迟以确保本机库在立即重新加载时不会返回相同的句柄。 JNA source code指出,在OSX上至少可以延迟2毫秒,并且在您的评论中,您似乎已经成功在OS上成功了10毫秒的延迟。

相关问题