我正在编写一个消耗大量内存的缓存应用程序.
希望我能够很好地管理自己的记忆,但是我只是在考虑如果我的内存不足会怎么做.
如果调用甚至分配一个简单的对象失败,即使是syslog调用也可能会失败?
编辑:好的,也许我应该澄清这个问题.如果malloc或new返回NULL或0L值,那么它实质上意味着调用失败,并且由于某种原因它无法为您提供内存.那么,在这种情况下做什么是明智的做法?
EDIT2:我刚刚意识到对"new"的调用会引发异常.这可以在更高的水平上捕获,所以我可以优雅地进一步退出.此时,甚至可以根据释放的内存量进行恢复.至少我应该在那一点上希望能够记录一些东西.因此,虽然我已经看到在新的之后检查指针值的代码,但这是不必要的.在C中,您应该检查malloc的返回值.
OOME是一类错误,通常你不应该从中恢复.但是如果它被隐藏在一个线程中,或者有人捕获它,那么应用程序可能会进入一个它不会退出的状态,但是没有用处.有关如何防止这种情况的任何建议,即使面对使用可能愚蠢地尝试捕获Throwable或Error/OOME的库?(即您没有直接访问权限来修改源代码)
根据C++参考,您可以通过以下方式新建一个对象:
MyClass * p1 = new MyClass;
Run Code Online (Sandbox Code Playgroud)
或者
MyClass * p2 = new (std::nothrow) MyClass;
Run Code Online (Sandbox Code Playgroud)
第二个将返回空指针而不是抛出异常.
但是,根据我的经验,我几乎看不到这个版本.
例如,谷歌不建议在他们的代码中使用异常,但我们可以看到他们没有在Chromium中使用nothrow版本.
是否有任何理由我们更喜欢默认的一个而不是一个?即使在没有使用异常的项目中?
- 编辑 -
跟进问题:我应该检查返回值malloc()吗?
看起来,相反,许多人建议检查malloc的返回值,有些人说是因为:
许多分配失败与内存不足无关.碎片可能导致分配失败,因为即使有足够的可用内存,也没有足够的连续空间可用.
这是真的?为什么我们在这种情况下对待malloc()和new()不同?
我是从C++来的Java.在C++世界中,我们注意异常安全,并注意,mutator可以在mutator本身抛出的异常或它委托给它的方法(最小,强,无抛出)时提供不同的保证.实现具有强异常保证的方法需要保证一些基本操作永远不会抛出异常.JLS声明哪些操作可以抛出哪种异常,但VirtualMachineError错误会带来问题.答曰JLS:
内部错误或资源限制阻止Java虚拟机实现Java编程语言的语义; 在这种情况下,
VirtualMachineError抛出一个子类的实例 .
JLS没有再说了VirtualMachineError."内部错误"意味着JVM中的一个错误,所以我对这种情况不感兴趣:面对JVM中的错误,所有的赌注都是关闭的.但是那个"资源限制"案例呢?是否存在因资源限制而保证永不失败的操作?
假设您拥有通常永远不会失败的功能,例如:
std::string convert_integer_to_string(int x);
Run Code Online (Sandbox Code Playgroud)
在市政当局,这将是一个候选人noexcept.但是,实现最有可能涉及动态内存管理,因此在为运算符分配内存时,它总是会抛出std :: bad_allocnew.
是否建议将该函数注释为noexcept?
从实际的角度来看,以合理的方式处理内存不足的情况是极其困难的.大多数程序只假设有足够的可用内存.std::terminate正如在某个noexcept函数抛出时所发生的那样,调用std::bad_alloc在这种情况下似乎是合理的.
对我来说noexcept是某种形式的文档.这是一个承诺,你(或优化器)可以安全地假设这个函数永远不会抛出.如果您正在编写一个不关心内存不足情况的应用程序,那么它仍然是一个有效的假设.
我想最安全的建议是noexcept如果std::bad_alloc抛出异常就永远不要使用.另一方面,我想知道是否有优势可以使用noexcept,假设您不关心内存不足的情况(即,如果std::terminate可以).
我今天刚开始阅读Effective C++并且到了作者谈论operator new的地步.
这本书很好地解释了如何捕获(具有不同程度的优雅)std :: bad_alloc异常,如果内存不足,操作员可以引发该异常.
我的问题是:当没有足够的内存来实例化一个对象时,你经常检查一下这个案例,如果有的话?为什么?麻烦值得吗?
我有一个适用于大量数据的应用程序,我想,可能是,有时候OutOfMemoryException会被抛出(半年来,我没有一个例外,但我只是想知道所有这些).正如我所调查的那样,在此异常之后,我无法继续执行我的程序.
是否有任何好的模式来处理这些异常,尤其是使用IDisposable类?
c++ ×4
exception ×3
java ×2
jvm ×2
.net ×1
bad-alloc ×1
c ×1
c++11 ×1
correctness ×1
idisposable ×1
linux ×1
malloc ×1
new-operator ×1
noexcept ×1
try-catch ×1