gpt4 book ai didi

java - .net 的 GC.KeepAlive 的 Java 等价物是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:25:03 24 4
gpt4 key购买 nike

.NET 有一个名为 GC.KeepAlive(Object) 的函数.它的唯一目的是确保引用对象的生命周期持续到代码流到达调用为止。

这通常是不必要的,除非与 native 代码进行互操作。

我有一个情况,我有一个通过 JNI 访问的 C++ 对象图,其中某些根对象需要保持 Activity 状态以保持子对象 Activity 。根对象和子对象在 JVM 领域都有镜像。但是,如果在 C++ 端收集并释放根对象(通过 SWIG 生成的终结器),则子对象将变得无效,因为它们的 C++ 支持对象将被释放。

这可以通过确保作为对象图根的局部变量的生命周期超过子对象的最后一次使用来解决。所以我需要一个不对对象做任何事情的惯用函数,但不会被优化掉或移动(例如,从循环中吊起)。这就是 GC.KeepAlive(Object) 在 .NET 中所做的。

Java 中的近似等价物是什么?

PS:一些可能的说明性代码:

class Parent {
long ptr;
void finalize() { free(ptr); }
Child getChild() { return new Child(expensive_operation(ptr)); }
}

class Child {
long ptr;
void doStuff() { do_stuff(ptr); }
}

// BAD CODE with potential for SIGSEGV
for (Parent p : getParents()) {
p.getChild().doStuff();
}

问题在于 GC 释放 Parent p 将在执行 doStuff 时释放分配给 Child 的内存。在实践中观察到 GC 会这样做。如果 GC.KeepAlive 可用,可能的修复方法:

// BAD CODE with potential for SIGSEGV
for (Parent p : getParents()) {
p.getChild().doStuff();
GC.KeepAlive(p);
}

我可以,例如在 p 上调用 toString,但我不会对其输出做任何事情。我可以暂时将 p 插入数组,但我怎么知道 JVM 不会丢弃存储?等等

最佳答案

我猜你可以使用 JMH Blackhole为了这。它旨在确保引用不会在基准测试中被淘汰,因此它应该可以工作。

基本上它只是将给定的对象引用与存储的 volatile 引用进行比较,并以较小且递减的概率重新分配后者(存储成本高,因此它被最小化)。

关于java - .net 的 GC.KeepAlive 的 Java 等价物是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22457002/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com