你怎么知道主要是退出了?

Nic*_*son 6 c++ static posix program-entry-point exit

在C和C++,atexit函数的调用任一内部exit或之后main返回(其名义上调用exit:__libc_start_main(argc,argv) { __libc_constructors(); exit(main(argc,argv)); }).

有没有办法找出我们是否在退出序列内?注册了C++全局和局部静态的析构函数atexit,因此您的代码在此阶段肯定可以调用.(有趣的是,在某些平台上,如果你试图在里面创建一个C++本地静态对象exit,它会在退出锁上死锁!)

到目前为止,我最好的尝试如下:

static bool mainExited = false;
static void watchMain() {
  static struct MainWatcher {
    ~MainWatcher() { mainExited = true; }
  } watcher;
}
Run Code Online (Sandbox Code Playgroud)

当您想要注意退出时,您可以随时调用watchMain()mainExited告诉您退出序列是否已经开始 - 当然,如果稍后初始化的本地静态对象正在破坏!

可以改进技术来纠正这个问题,还是有另一种方法可行?

除了 - 用例!

虽然从语言的角度来看这个问题很有意思(有点像"我可以判断我是否在一个catch区块内吗?"),但概述一个用例也很有用.我在编写一些代码时遇到了这个问题,这些代码将在加载JVM和没有加载JVM的情况下运行(直接调用或通过JNI调用).JVM退出后,将atexit调用C 处理程序,JNI_OnUnload如果类加载器未卸载JNI共享库,则不会调用它们.

由于共享库的对象可以通过显式销毁(并且应该释放它们的资源)来破坏,并且通过在退出时清理,我需要安全地区分这两种情况,因为当我们到达退出代码时JVM就消失了!基本上没有一点嗅探,我无法在JNI规范/文档中找到共享库来了解JVM是否仍然存在,如果它已经消失,那么尝试释放我们的引用肯定是错误的到Java对象.

Pup*_*ppy 7

这里真正的问题是你列出的所有权语义搞砸了.JVM有点拥有你的共享库,但也有点没有.您有一堆Java对象的引用,有时您需要清理,但有时您不需要清理.

这里真正的解决方案是不将Java对象的引用保持为全局变量.然后,无论出于何种原因卸载库,您都不需要知道JVM是否仍然存在.只需从Java引用的对象内部继续引用Java对象,然后让JVM关心它是否需要释放它们.

换句话说,首先不要让自己负责清理退出.