当前位置: 首页 > 知识库问答 >
问题:

从JNI代码使对象引用为空

陆臻
2023-03-14

这里是我的问题的一个抽象。我想在JNI函数中将java代码中的对象引用设置为null。例如:

// -- java code --
String s="this is a new string";
func(s);                        //passing the object to the JNI function.
System.out.println(s);
JNIEXPORT void JNICALL
Java_func_test(JNIEnv *env, jobject this, jobject todel)
{
    (*env)->DeleteGlobalRef(env,todel);
}

内部错误(src/hotspot/share/gc/shared/oopstorage.cpp:697),PID=59362,tid=59363断言(block!=__null)失败:JNI Global:无效版本0x00007F66ED673788

JRE版本:OpenJDK运行时环境(14.0)(slowdebug build 14-internal+0-adhoc.manavjeet.jdk14)Java VM:OpenJDK 64位服务器VM(slowdebug 14-internal+0-adhoc.manavjeet.jdk14,混合模式,分层,压缩oops,g1 gc,linux-amd64)问题帧:V[libjvm.so+0xF684EB]OOPStorage::Release(Oopdesc*const*)+0x49

将写入核心转储。默认位置:可以使用“/usr/share/apport/apport%p%s%c%d%p%e”处理核心转储(或转储到/home/manavjeet----/Core.59362)

包含更多信息的错误报告文件保存为:/home/manavjeet/--/hs_err_pid59362.log

如果您想提交错误报告,请访问:https://bugreport.java.com/bugreport/crash.jsp Current thread is 59363 dumning core...fish:“./java-slowdebug helloworld”ferenced by signal abrt(Abort)

通过这一点,我明白这是非常错误的。谁能指出错误,并建议正确的方法,将java中的对象引用设置为NULL。

共有1个答案

东方新霁
2023-03-14

Java是按值传递的。调用func(s)复制引用s并将其提供给func,这不能更改原始引用。null不是对象;这是一个特别的参考。这意味着func不能将s设置为null,因为它不能更改s,只能更改它后面的对象。仅仅作为本机方法并不能赋予func打破语言规则的魔力。JNI主要用于与语言之外的功能进行接口。除非找到一种方法来窥视调用方的字节码并改变其堆栈帧,否则无法做到这一点。

此外,DeleteGlobalRef不是这样工作的。它只能释放newglobalref所做的引用,您可以调用这些引用来记住对本机函数的调用之间的状态。Todel这里是一个本地引用,为对本机方法的每次调用重新创建。我相信您可以deleteLocalref删除它,但这不会起任何作用。

JNIEXPORT void JNICALL
Java_func_test(JNIEnv *env, jobject this, jobject todel)
{
    (*env)->DeleteLocalRef(env, todel);
}

这至少不会崩溃,但它仍然不能修改调用方拥有的引用;基本上相当于

void func(Object todel) {
    todel = null;
}

如果您真的非常想这样做,您可以将引用框入另一个对象,并对其进行变异:

public class Box<T> {
    public T ref;
    public Box() { this(null); }
    public Box(T ref) { this.ref = ref; }
    public String toString() {
        return "Box(" + System.identityHashCode(ref) + ": " + ref + ")";
    }
}

<T> void func(Box<T> box) { box.ref = null; }
// as I said; native methods are not magic
// rewriting func with the JNI does not make it more powerful; just more inscrutable

void test() {
    var s = new Box<>("this is a new string");
    func(s);
    System.out.println(s); // "Box(0: null)"
}

但是...你为什么要?

 类似资料:
  • 问题内容: 我需要使用NDK以及JNI将一些功能实现到Android应用程序中。 这是我所写的C代码: 我的问题或多或少在代码内得到了解释。也许还可以:函数(jobject)的返回类型可以吗? 现在,NDKTest.java: 当我尝试运行代码时,它不起作用。 问题答案: 既然是内部类,那么获得它的方法就是 内部类的约定在权威规范中并未真正明确记录,但是根深蒂固地存在于如此多的工作代码中,因此不太

  • 这已经超出我的想象了,我们开始吧。 我正在用C语言设置一个函数指针,该指针带有一个Java接口对象,看起来像Java端的接口对象: 其中,是只有一种方法的接口: 而指的是Java本机方法,它在C端反映如下: 所有这些都是基于JNI中使用接口实现回调函数编写的 我已经尝试在C端调用Java中定义的方法,它可以工作(就像上面的链接一样),但是现在我正在尝试在C下设置这样的上的值 因此,稍后我想把作为一

  • 我有以下C#类: 总而言之,区域设置有区域、按钮和字段。区域有中心和东部。中心和东部拥有产权。Fields包含具有属性firstName、lastName和ChooseLocale的标签。 在一个名为GetLocale的方法中,我有以下代码: 运行代码时,在以下行抛出一个“NullReferenceException was unhandled by user code”: 我设置属性title、

  • 问题内容: 我有一个C程序,它使用JNI在Java存储中存储一些对象。(在有人问之前,这里需要使用Java存储,而我必须用C编写一个客户端,该客户端才能从该存储中添加和检索对象)。 我制作了程序,并尝试添加100000个大小为1KB的对象。但是在仅添加50000个对象之后,我得到了“内存不足”消息(请注意,每当我无法使用NewStringUTF和NewByteArray函数分配新的字符串或字节数组

  • 问题内容: 我对JNI相对较新,并且掌握了使用JNI处理Java对象中的整数和数组的基本知识。现在,我正在尝试修改/访问Java对象中的Java对象。 我一直在互联网和Stack Overflow上进行搜索,但还没有找到执行该操作的方法。 这是例子。 在Java中: 在JNI中,如何通过ObjectTwo从ObjectOne访问“ buff”?我尝试过这样的事情… 我做错了什么吗? 问题答案: 在

  • 本文向大家介绍Python中对象的引用与复制代码示例,包括了Python中对象的引用与复制代码示例的使用技巧和注意事项,需要的朋友参考一下 可以说Python没有赋值,只有引用。你这样相当于创建了一个引用自身的结构,所以导致了无限循环。为了理解这个问题,有个基本概念需要搞清楚。 Python没有「变量」,我们平时所说的变量其实只是「标签」,是引用。 python中,"a=b"表示的是对象a引用对象