【问题标题】:Context switched native thread can't attach to JVM上下文切换的本机线程无法附加到 JVM
【发布时间】:2013-10-06 05:17:58
【问题描述】:

我们有一个 Java 服务器(Linux 64 位)应用程序,它使用本机代码来处理它的内容。本机代码还处理所有多线程问题,并且最近使用boost::context 通过光纤切换进行了增强。

我们现在面临的问题是AttachCurrentThread 对光纤交换线程失败。经过长时间的调试和测试,我们找到了造成这种情况的原因:JVM 似乎拒绝了与创建时给出的堆栈指针不同的线程。

我们通过简单地从带有修改(但有效)rsp 的 pthread 附加到 JVM 来验证这一点,当 rsp 被修改时失败。

一种可能的解决方法是引入某种事件处理机制来将回调与光纤交换线程分离,但我真的很想避免这种情况。

有人知道解决方法吗?

是否可以禁用堆栈检查(Oracle Java 1.7.0_40,64 位)?

我们可以修改本机 pthread 以指向正确的堆栈帧(我怀疑我们可以)吗? (我们不能提前设置栈帧)。

【问题讨论】:

  • 我知道它不能完全回答您的问题,但您可以尝试用 Java 世界中的一些纤维实现替换您的 boost::context 纤程(在 C++ 中实现)。在这种情况下,它们通常被称为协程。这里有一些现有的实现:Available Coroutine Libraries in Java
  • 您找到解决方案了吗?我正在尝试使用 Boost.Coroutine 并且需要在这样的例程中从 JNI 回调到 Java 空间,这会导致很多失败......

标签: java linux boost java-native-interface


【解决方案1】:

免责声明:这不是一个真正的答案,因为我没有直接解决 RSP 切换问题,但是太长了,无法发表评论。

根据我的经验,您应该只附加一次本机线程,并在它退出之前完全分离一次。如果您不知道是否已附加,请使用此代码:

jint rv = vm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (rv == JNI_EDETACHED) {
    vm->AttachCurrentThread((void**)&env, 0);
}

我建议首先,确保在创建任何关联的纤程之前恰好附加到线程一次,并在每个本机线程退出之前从它完全分离一次(或者根本不分离,如果本机线程没有终止)。

【讨论】:

    猜你喜欢
    • 2015-09-24
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2011-07-27
    • 2012-01-12
    • 2014-01-05
    相关资源
    最近更新 更多