相关疑难解决方法(0)

"内存不足"是一个可恢复的错误?

我已经编程了很长时间,我看到的程序,当它们内存不足时,会尝试清理并退出,即优雅地失败.我不记得上次我看到一个人真正尝试恢复并继续正常运行.

如此多的处理依赖于能够成功分配内存,特别是在垃圾收集语言中,似乎内存不足错误应归类为不可恢复.(不可恢复的错误包括堆栈溢出等.)

使其成为可恢复错误的令人信服的理由是什么?

language-agnostic memory memory-management exception error-recovery

74
推荐指数
7
解决办法
7950
查看次数

C++/Windows:如何报告内存不足异常(bad_alloc)?

我目前正在为Windows MSVC++(9.0)应用程序(即异常结构和类型/继承,调用堆栈,错误报告和日志记录等)开发基于异常的错误报告系统.

我现在的问题是:如何正确报告和记录内存不足错误?

当发生此错误时,例如,作为op bad_alloc抛出的错误,new可能存在许多"功能"不可用,主要涉及进一步的存储器分配.通常,我将异常传递给应用程序,如果它已经在lib中抛出,然后使用消息框和错误日志文件来报告和记录它.另一种方式(主要用于服务)是使用Windows事件日志.
我遇到的主要问题是汇编错误消息. 为了提供一些错误信息,我想定义一个静态错误消息(可能是字符串文字,更好的是消息文件中的条目,然后使用FormatMessage)并包含一些运行时信息,如调用堆栈.
这种使用所需的功能/方法也是如此

  • STL(std::string, std::stringstream, std::ofstream)
  • CRT(swprintf_s, fwrite)
  • 或Win32 API(StackWalk64, MessageBox, FormatMessage, ReportEvent, WriteFile)

除了在MSDN上记录,所有这些都在Windows中更多(Win32)或更少(STL)闭源,所以我真的不知道它们在低内存问题下的行为.

为了证明可能存在问题,我写了一个琐碎的小应用程序,引发了一个bad_alloc:

int main()
{
    InitErrorReporter();  

    try
    {
        for(int i = 0; i < 0xFFFFFFFF; i++)
        {
            for(int j = 0; j < 0xFFFFFFFF; j++)
            {
                char* p = new char;
            }
        }
    }catch(bad_alloc& e_b)
    {
        ReportError(e_b);
    }

    DeinitErrorReporter();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

抛出两个没有连接调试器的实例(在Release config,VS 2008中),但"没有发生",即没有来自ReportEvent或WriteFile的错误代码我在错误报告中内部使用.然后,使用一个w/o调试器启动一个实例,让他们尝试使用ReportError行上的断点一个接一个地报告错误.对于连接了调试器的实例(正确报告并记录错误,即使使用LocalAlloc没有问题),这也很好!但是taskman展示了一个奇怪的行为,在应用程序退出之前释放了大量内存,我想当抛出异常时.


请考虑可能有多个进程[编辑]和多个线程[/ edit]消耗大量内存,因此释放预先分配的堆空间不是一个安全的解决方案,以避免想要报告的进程的低内存环境错误.

先感谢您!

c++ windows error-reporting out-of-memory

8
推荐指数
1
解决办法
2623
查看次数

C++中的软(非弱)引用 - 是否可能?有实施吗?

在C++中,我正在使用boost::shared_ptrboost::weak_ptr自动删除不再需要的对象.我知道这些工作与引用计数.

在Java中,内存是由垃圾收集器,其consideres管理的内置对象引用为,WeakReference因为SoftReference在之间(可通过GC收集,但可能还有生存的GC)的东西,这是非常方便的用于缓存对象一段时间,但一旦可用内存不足就将它们丢弃.

所以现在我回到了C++中,我错过了软引用的安慰.我想知道软引用是否适用于引用计数.当清除对象的最后一个引用,并且仍然有一个引用时,它什么时候会被删除?我可以想到一些方案,但对我来说似乎都不聪明.

为了防止软引用和引用计数有适当的语义,我想知道这是否已经实现,可能是以一种甚至兼容的方式boost::shared_ptr(或C++ TR1等效std::shared_ptr的方式).

如果两个问题的答案都是否定的,那么对象缓存场景中的替代方案是什么?

编辑: 当然我说的是缓存实际上很有用的情况,因为构造对象的成本很高(想想几次访问数据库和网络查询),但是有太多东西要永远保存它们.

c++ boost memory-management soft-references shared-ptr

6
推荐指数
2
解决办法
1681
查看次数