如何避免“交换死亡”在开发过程中? [英] How to avoid the "swapping of death" during development?

查看:147
本文介绍了如何避免“交换死亡”在开发过程中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能每个人在开发过程中都遇到这个问题至少一次:

Probably everyone ran into this problem at least once during development:

while(/*some condition here that somehow never will be false*/)
{
    ...
    yourvector.push_back(new SomeType());
    ...
}

您看到程序开始耗尽所有系统内存,你的程序挂起,你的系统开始交换像疯了。如果你不能足够快地识别问题,杀死进程,你可能会得到一个无响应的系统在几秒钟内,你的鼠标指针甚至不移动。您可以用内存不足错误(可能需要几分钟时间)等待程序崩溃,或者在计算机上点击重置。

As you see the program starts to drain all system memory, your program hangs and your system starts to swap like crazy. If you don't recognize the problem fast enough and kill the process you probably get an unresponsive system in seconds where your mouse pointer don't even moving. You can either wait your program crash with "out of memory" error (which may take several long minutes) or hit the reset on your computer.

如果您无法跟踪bug,立即,那么你将需要几个测试和重置,以找出是非常讨厌...

If you can't track down the bug immediately then you will need several tests and resets to find out which is very annoying...

我正在寻找一种可能的跨平台方式防止这种不知何故。最好的是一个调试模式代码,如果它分配了太多的内存,退出程序,但我如何跟踪分配了多少内存?
覆盖全局新的和删除操作符不会有帮助,因为我将在删除中调用的自由函数不会给出任何想法释放多少字节。

I'm looking for a possibly cross-platform way to prevent this somehow. The best would be a debug mode code that exits the program if it allocated too much memory, but how can I keep track how much memory is allocated? Overriding the global new and delete operators won't help, because the free function I would invoke in the delete won't give any idea how many bytes are freed.

任何想法赞赏。

推荐答案


覆盖全局新增和删除操作符,因为我将在删除中调用的自由函数不会给出任何想法释放多少字节。

Overriding the global new and delete operators won't help, because the free function I would invoke in the delete won't give any idea how many bytes are freed.

它这样。这里有一个完整的框架用于重载全局内存操作符(将其放在一些 global_memory.cpp 文件中):

But you can make it so. Here's a full framework for overloading the global memory operators (throw it in some global_memory.cpp file):

namespace
{   
    // utility
    std::new_handler get_new_handler(void)
    {
        std::new_handler handler = std::set_new_handler(0);
        std::set_new_handler(handler);

        return handler;
    }

    // custom allocation scheme goes here!
    void* allocate(std::size_t pAmount)
    {

    }

    void deallocate(void* pMemory)
    {

    }

    // allocate with throw, properly
    void* allocate_throw(std::size_t pAmount)
    {
        void* result = allocate(pAmount);

        while (!result)
        {
            // call failure handler
            std::new_handler handler = get_new_handler();
            if (!handler)
            {
                throw std::bad_alloc();
            }

            handler();

            // try again
            result = allocate(pAmount);
        }

        return result;
    }
}

void* operator new(std::size_t pAmount) throw(std::bad_alloc)
{
    return allocate_throw(pAmount);
}

void *operator new[](std::size_t pAmount) throw(std::bad_alloc)
{
    return allocate_throw(pAmount);
}

void *operator new(std::size_t pAmount, const std::nothrow_t&) throw()
{
    return allocate(pAmount);
}

void *operator new[](std::size_t pAmount, const std::nothrow_t&) throw()
{
    return allocate(pAmount);
}

void operator delete(void* pMemory) throw()
{
    deallocate(pMemory);
}

void operator delete[](void* pMemory) throw()
{
    deallocate(pMemory);
}

void operator delete(void* pMemory, const std::nothrow_t&) throw()
{
    deallocate(pMemory);
}

void operator delete[](void* pMemory, const std::nothrow_t&) throw()
{
    deallocate(pMemory);
}

然后你可以这样做:

    // custom allocation scheme goes here!
    const std::size_t allocation_limit = 1073741824; // 1G
    std::size_t totalAllocation = 0;

    void* allocate(std::size_t pAmount)
    {
        // make sure we're within bounds
        assert(totalAllocation + pAmount < allocation_limit);

        // over allocate to store size
        void* mem = std::malloc(pAmount + sizeof(std::size_t));
        if (!mem)
            return 0;

        // track amount, return remainder
        totalAllocation += pAmount;
        *static_cast<std::size_t*>(mem) = pAmount;

        return static_cast<char*>(mem) + sizeof(std::size_t);
    }

    void deallocate(void* pMemory)
    {
        // get original block
        void* mem = static_cast<char*>(pMemory) - sizeof(std::size_t);

        // track amount
        std::size_t amount = *static_cast<std::size_t*>(mem);
        totalAllocation -= pAmount;

        // free
        std::free(mem);
    }

这篇关于如何避免“交换死亡”在开发过程中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆