Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 原生C++;图书馆-谁必须释放内存?如何释放?_Android_C++_Memory Management_Native - Fatal编程技术网

Android 原生C++;图书馆-谁必须释放内存?如何释放?

Android 原生C++;图书馆-谁必须释放内存?如何释放?,android,c++,memory-management,native,Android,C++,Memory Management,Native,这是关于Android的。情况: C++库和java包装类加上本机函数(JNI),用于从库中处理C++类。当普通java代码需要C++对象时,它创建相应的java包装对象,通过本地函数创建C++对象,并记住指向“长”变量中的本地对象的指针。在接下来的所有动作中,包装器都会给出指向本机函数等的指针 问题是: 如何释放所有分配的C++对象?目前,每个包装类都有“终结”方法,在这里调用了用于释放C++对象的本机函数,但是Android不能保证调用“终结”!在另一方面,通常C++库不知道java代码分

这是关于Android的。情况:

C++库和java包装类加上本机函数(JNI),用于从库中处理C++类。当普通java代码需要C++对象时,它创建相应的java包装对象,通过本地函数创建C++对象,并记住指向“长”变量中的本地对象的指针。在接下来的所有动作中,包装器都会给出指向本机函数等的指针

问题是:

<>如何释放所有分配的C++对象?目前,每个包装类都有“终结”方法,在这里调用了用于释放C++对象的本机函数,但是Android不能保证调用“终结”!在另一方面,通常C++库不知道java代码分配了多少种C++对象。
当java应用程序终止时,剩余分配的内存会发生什么情况?当操作系统卸载库时,Android会自动释放本机库中使用的整个堆吗?

由于范例的不同,必须将显式破坏合并到使用C++资源的引擎下实现的java对象中。因此,可以使用
close()
或其他类似方法。JNI也会出现同样的问题,因此这些问题的答案将适用于您:

至于结束时的记忆问题,我认为通常最好不要依赖于此。如果你得到一个干净的状态,valgrind等可以确保你没有泄漏


但从技术角度来看——由于Android是基于Linux的,我想它会做通常的事情,并在进程关闭时释放所有内存。利用这个优势,可以使程序退出的速度比显式释放内存更快(对于只使用其他方法的专家来说,这确保程序保持正确性,并且在运行时不会泄漏)。

在进程生命周期结束时,所有进程内存(java和C++堆)都将被系统释放和回收。但有一点是,Android活动关闭并不一定会结束整个过程。我不确定那里的进程关闭策略是什么

另一方面,依赖垃圾收集和finalize()对我来说似乎是一个可靠的设计。您声称“Android不保证
finalize()
”。你对此有什么理由吗?”因为如果它附带了一个免责声明“当对象作为进程关闭的一部分被释放…”,那么我们仍然很好


如果你是超级偏执狂,你可以编写你自己的malloc()/free()/realloc()包装器,存储所有分配对象的列表,并引入一个清理函数来遍历列表并释放它们。但是,包含Java对象的对象可能会以一种奇怪的僵尸状态结束,在这种状态下,内存已经从它们下面释放出来。这是一个很棘手的命题,很容易出错。所以我还是要说——对垃圾收集器有信心。缺少它将是。。。令人不安。

我们正在使用JNIs,我们遇到了这样的问题

实际上,问题在于我们重载finalize()来进行清理。我们通过删除finalize()并创建一个clean()来解决问题。这个清除()调用JNI函数,它执行适当的删除(并且将C++指针设置为NULL,以防万一)。我们将Cube()称为C++中的删除(例如当变量超出范围)时。
这对我们有用。我希望它对你有用。祝你好运

你会在这里找到你需要的答案:这里讨论的实质是“最终确定不确定”,我在这里的问题中指出了这一点。@rsp的建议只适用于简单的情况——当整个对象的生命周期都在一段连续的代码中时。今天的事件驱动编程通常包含更复杂的场景。关于您的链接,请参阅我对JACH的回答,问题也是一样的。C++对象的一些包装可以深入到程序的对象层次,也可以知道这个层次的最高层次,没有人知道它。“我想它会做普通的事情,并且在进程关闭时释放所有内存”——我希望。“在进程生命周期结束时,所有进程内存(java和C++堆)都将被系统释放”,如果这是肯定的,它是我应该做的。“Android活动关闭不一定会结束流程”-是的。主要活动完成后需要一段时间,也可以使用System.exit或android.os.Process.killProcess强制执行。“你对此有引用吗?”-不完全是,但这是我从这里引用的链接和我以前读过的其他链接中得到的印象。事实上,我对它进行了测试,将Log.w放在finalizer中-在过程结束之前或之后都没有任何消息“如果你是超级偏执狂,你可以自己写…”-是的,我考虑过类似的事情。在JNI_OnUnload()上启动清理。不幸的是,JNI_OnUnload从未也被称为。如果确定系统将释放lib上的所有内容。卸载,不必浪费时间来编写这样的清理。几乎每个人都在为这个方法说话,但是想象一下:java对象X中的C++指针,它位于y中的对象y中。你可以在x中创建方法CULL(),但是你也需要在Y和Z中定义这种方法!也就是说,只针对每一个案例来模拟整个java程序中C++析构函数的样式。我更倾向于认为Android将释放整个堆,这是我们必须期待的正常行为。