- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想执行以下循环:
for(absolute_date CURRENT_DATE = START_DATE; CURRENT_DATE.COMPARE_TO(END_DATE) <= 0; CURRENT_DATE.SHIFT_SELF(TIMESTEP))
{
CURRENT_STATE = Propagator.PROPAGATE(CURRENT_DATE);
}
其中 CURRENT_STATE
是 state
类的对象。 propagator::PROPAGATE()
是一种返回 state
类对象的方法。
我的 state
类实际上是我通过 JNI 调用 API 调用的 Java 库类的类包装器。我遇到的问题是我想用 DeleteLocalRef
删除本地 java 引用以防止内存泄漏(特别重要,因为我将循环数千次)。
但是,由于在我的 state
类析构函数中调用了 DeleteLocalRef
,因此当赋值的 RHS 返回时,对 java jobject 的引用被销毁,从而使 CURRENT_STATE 无效,因为它包含对已删除的工作项目的引用。
如何避免这种情况?
@Wheezil
关于您的第一点——因为我正在使用调用 API,即在 C++ 中创建一个虚拟机并调用 Java 函数,我认为我不需要转换为全局引用(因为所有本地引用在 JVM 启用之前仍然有效)销毁或直到线程被分离)。在这种情况下,我不会分离线程并将其重新附加到 JVM,因此本地引用永远不会被删除。对我来说重要的是确保在 JVM 中删除本地引用。
关于第二点 - 我已经通过设置我的复制构造函数/赋值运算符 = delete 来禁止复制。我的问题更具体地是关于如何确保删除这些引用。
我的状态类如下所示:
state::state(JNIEnv* ENV)
{
this->ENV = ENV;
this->jclass_state = ENV->FindClass("/path/to/class");
this->jobject_state = nullptr;
}
state::~state()
{
if(DOES_JVM_EXIST())
{
ENV->DeleteLocalRef(this->jclass_state);
ENV->DeleteLocalRef(this->jobject_state); //PROBLEMATIC
}
}
state::state(state&& state_to_move)
{
this->ENV = state_to_move.ENV;
//move jobjects from mover => new object
this->jobject_state = state_to_move.jobject_state;
this->jclass_state = state_to_move.jclass_state;
}
state& state::operator =(state&& state_to_move)
{
this->ENV = state_to_move.ENV;
//move jobjects from mover => current object
this->jobject_state= state_to_move.jobject_state;
this->jclass_state = state_to_move.jclass_state;
return *this;
}
更详细地描述我面临的问题:propagator::PROPAGATE()
方法按值返回一个state
对象(当前堆栈已分配)。一旦此函数返回,就会发生以下情况:
1) 移动赋值运算符被调用。这会在 CURRENT_STATE
对象中设置 jobject_state
和 jclass_state
成员。
2) 为在 PROPAGATE() 函数中创建的 state
实例调用析构函数。这会删除对 jobject_state 的本地引用,因此 CURRENT_STATE 对象不再具有有效的成员变量。
最佳答案
从哪里开始... JNI 非常挑剔和无情,如果你不把事情做好,它就会崩溃。您的描述相当单薄(如果这没有帮助,请提供更多详细信息),但我可以做出很好的猜测。你的方法有几个问题。你大概在做这样的事情:
struct state {
state(jobject thing_) : thing(thing_) {}
~state() { env->DeleteLocalRef(thing); }
jobject thing;
}
第一个问题是存储本地引用是危险的。您不能在当前 JNI 框架之外挂起它们。所以将它们转换为全局:
struct state {
state(jobject thing_) : thing(env->NewGlobalRef(thing_)) {
env->DeleteLocaLRef(thing_);
}
~state() { env->DeleteGlobalRef(thing); }
jobject thing;
}
第二个问题是 jobject 基本上就像旧的 C++ auto_ptr<> —— 真的不安全,因为复制它会导致悬空指针和双重释放。所以你要么需要禁止复制状态并且可能只传递状态*,要么制作一个有效的复制构造函数:
state(const state& rhs) thing(env->NewGlobalRef(rhs.thing)) {}
这至少应该让您走上正轨。
更新:Ddor,关于本地与全局引用,this link描述得很好:“当执行从创建本地引用的本地方法返回时,本地引用变得无效。因此,本地方法不得存储本地引用并期望在后续调用中重用它。”您可以保留本地引用,但只有在严格的情况下。请特别注意,您不能将这些交给另一个线程,而您似乎没有这样做。另一件事——可以激活的本地引用总数是有限制的。令人沮丧的是,此限制未指定,但它似乎是特定于 JVM 的。我建议谨慎并始终转换为全局。
我以为我在某处读到过,您不需要删除 jclass,因为 FindClass() 总是返回相同的东西,但我很难验证这一点。在我们的代码中,我们也始终将 jclass 转换为全局引用。
ENV->DeleteLocalRef(this->jclass_state);
我必须承认对 C++ 移动语义的无知;只需确保未调用默认复制构造函数并且您的 jobject_state 未被释放两次。
this->jobject_state = state_to_move.jobject_state;
如果你的移动构造函数被调用而不是复制构造函数或赋值,我不知道你为什么会在临时对象的销毁时看到删除。正如我所说,我不是移动语义方面的专家。我总是让复制构造函数创建一个新的全局变量。引用。
关于java - 删除对象分配 JNI 调用 API 中的 jobject 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53176990/
我想做的是让 JTextPane 在 JPanel 中占用尽可能多的空间。对于我使用的 UpdateInfoPanel: public class UpdateInfoPanel extends JP
我在 JPanel 中有一个 JTextArea,我想将其与 JScrollPane 一起使用。我正在使用 GridBagLayout。当我运行它时,框架似乎为 JScrollPane 腾出了空间,但
我想在 xcode 中实现以下功能。 我有一个 View Controller 。在这个 UIViewController 中,我有一个 UITabBar。它们下面是一个 UIView。将 UITab
有谁知道Firebird 2.5有没有类似于SQL中“STUFF”函数的功能? 我有一个包含父用户记录的表,另一个表包含与父相关的子用户记录。我希望能够提取用户拥有的“ROLES”的逗号分隔字符串,而
我想使用 JSON 作为 mirth channel 的输入和输出,例如详细信息保存在数据库中或创建 HL7 消息。 简而言之,输入为 JSON 解析它并输出为任何格式。 最佳答案 var objec
通常我会使用 R 并执行 merge.by,但这个文件似乎太大了,部门中的任何一台计算机都无法处理它! (任何从事遗传学工作的人的附加信息)本质上,插补似乎删除了 snp ID 的 rs 数字,我只剩
我有一个以前可能被问过的问题,但我很难找到正确的描述。我希望有人能帮助我。 在下面的代码中,我设置了varprice,我想添加javascript变量accu_id以通过rails在我的数据库中查找记
我有一个简单的 SVG 文件,在 Firefox 中可以正常查看 - 它的一些包装文本使用 foreignObject 包含一些 HTML - 文本包装在 div 中:
所以我正在为学校编写一个 Ruby 程序,如果某个值是 1 或 3,则将 bool 值更改为 true,如果是 0 或 2,则更改为 false。由于我有 Java 背景,所以我认为这段代码应该有效:
我做了什么: 我在这些账户之间创建了 VPC 对等连接 互联网网关也连接到每个 VPC 还配置了路由表(以允许来自双方的流量) 情况1: 当这两个 VPC 在同一个账户中时,我成功测试了从另一个 La
我有一个名为 contacts 的表: user_id contact_id 10294 10295 10294 10293 10293 10294 102
我正在使用 Magento 中的新模板。为避免重复代码,我想为每个产品预览使用相同的子模板。 特别是我做了这样一个展示: $products = Mage::getModel('catalog/pro
“for”是否总是检查协议(protocol)中定义的每个函数中第一个参数的类型? 编辑(改写): 当协议(protocol)方法只有一个参数时,根据该单个参数的类型(直接或任意)找到实现。当协议(p
我想从我的 PHP 代码中调用 JavaScript 函数。我通过使用以下方法实现了这一点: echo ' drawChart($id); '; 这工作正常,但我想从我的 PHP 代码中获取数据,我使
这个问题已经有答案了: Event binding on dynamically created elements? (23 个回答) 已关闭 5 年前。 我有一个动态表单,我想在其中附加一些其他 h
我正在尝试找到一种解决方案,以在 componentDidMount 中的映射项上使用 setState。 我正在使用 GraphQL连同 Gatsby返回许多 data 项目,但要求在特定的 pat
我在 ScrollView 中有一个 View 。只要用户按住该 View ,我想每 80 毫秒调用一次方法。这是我已经实现的: final Runnable vibrate = new Runnab
我用 jni 开发了一个 android 应用程序。我在 GetStringUTFChars 的 dvmDecodeIndirectRef 中得到了一个 dvmabort。我只中止了一次。 为什么会这
当我到达我的 Activity 时,我调用 FragmentPagerAdapter 来处理我的不同选项卡。在我的一个选项卡中,我想显示一个 RecyclerView,但他从未出现过,有了断点,我看到
当我按下 Activity 中的按钮时,会弹出一个 DialogFragment。在对话框 fragment 中,有一个看起来像普通 ListView 的 RecyclerView。 我想要的行为是当
我是一名优秀的程序员,十分优秀!