【问题标题】:How to call a Java method through JNI letting the JVM garbage-collect the arguments?如何通过 JNI 调用 Java 方法让 JVM 垃圾收集参数?
【发布时间】:2019-03-31 11:28:41
【问题描述】:

我有一个本地应用程序,它启动一个 JVM 并通过 JNI API 调用一些方法。

大致来说,原生应用程序:

  1. 启动JVM;
  2. 使用PushLocalFrame 创建一个新框架;
  3. 构建一个Java对象x,通过JNI调用构造函数;
  4. PopLocalFrame(x) 弹出框架;
  5. 在JVM中调用一个长时间运行的函数foo(x),将创建的对象作为参数传递给CallObjectMethod
  6. 终止。

问题在于,在相同的情况下,第 5 步会崩溃并显示 java.lang.OutOfMemoryError。这是出乎意料的,因为当从仅 JVM 的应用程序调用 Java 函数时,它通常不会使用太多内存。

使用 VisualVM 进行堆转储我发现有许多我没想到的“GC 根(Java 框架)”。我最好的解释是:

  1. foox 中获取一些字段并在其中存储内容;
  2. 在执行foo 期间,JVM 无法垃圾收集x,以及其中存储的任何内容。

那么,有没有办法通过 JNI 接口调用 Java 方法,让 JVM 垃圾收集参数?

Weak global references 几乎是我想要的,但我不知道如何使用它们,因为理论上它们可以在创建后立即被垃圾收集,然后作为参数传递给函数调用。

【问题讨论】:

    标签: java garbage-collection jvm java-native-interface


    【解决方案1】:

    在处理本机资源时,您不应指望垃圾收集来释放内存。

    相反,为包装原生对象或句柄的每个 Java 类实现 Closable 接口,并确保在取消引用之前关闭每个对象。

    您可以使用try (<Allocate Closables Here>) { <Use Them Here> } 语法来自动关闭对象。

    【讨论】:

      猜你喜欢
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 2016-08-16
      相关资源
      最近更新 更多