我正在尝试创建C ++类来封装Vulkan初始化过程(在一个非常基本的水平上,我仍在学习中),而我的设置方法要求将vulkan设备传递给显式的“销毁”清除功能。我将所有初始化都放在try-catch块中;问题在于,如果在初始化过程中引发异常,则对象将被销毁,而我将无法调用“ destroy”函数。
在伪代码中:
try{
DeviceObject device; // constructor initializes
SomeResource resource(device);
OtherResource other(device); // suppose an exception is thrown here
while(programRuns){
// do something
}
// end of program
other.destroy(device);
resource.destroy(device);
device.destroy();
}
catch (myException e){
showError(e);
}
在这种情况下,如果在运行时引发异常,则不会调用我的destroy函数,并且仅在成功终止程序后调用它们。
我想到了几种不同的方法来处理这种情况,并确保明确清理资源,但是我的问题是:我必须这样做吗?我知道我“应该”,但是如果程序崩溃并退出,操作系统会处理清理创建的资源,还是会在系统GPU(或类似的东西)上留下垃圾?
答案 0 :(得分:2)
典型OS(包括Windows,Linux,Android等)在销毁进程时会清理进程的所有资源。这包括回收该进程专有的所有内存,关闭该进程打开的文件和网络连接,减少共享资源的引用计数等。其中包括销毁GPU上下文以及与它们关联的任何内存或其他资源。因此,不,您不会在程序崩溃时不清理而浪费系统资源。
实际上,某些程序故意选择也不在清除/故意退出时进行清除,因为在此情况下,操作系统通常比调用一堆应用终止代码要快。顾名思义,该代码不经常使用,因此甚至可能从未从磁盘进行页面调入,它通常比释放操作系统级别的资源(例如,为不拥有操作系统级资源的对象调用析构函数。
在退出时进行优雅清理(清理或崩溃)的主要原因是,泄漏检测工具可以帮助您查找非终止泄漏。如果您泄漏所有内容,则会报告有关您已终止资源泄漏的报告-这可能表明无限期增长的泄漏问题-容易在噪音中流失。
答案 1 :(得分:0)
根据基于进程的OS的定义,给定进程的所有资源在其终止时都会释放。
未预料到的异常只是进程终止的一种方式。您甚至无法捕捉到其他一些崩溃信息,例如堆栈溢出。因此,操作系统必须清除该混乱情况。
我还要补充一点,如果您坚持使用C ++中的RAII(例外),则在堆栈展开时,应用程序本身会正确销毁所有内容。