2011-05-31 75 views
3

我正在制作一个将要使用许多动态创建对象(光线追踪)的应用程序。我不是一次又一次地使用[new],而是认为我只是制作一个简单的内存系统来加快速度。在这一点上它非常简单,因为我不需要太多。新增内存大量增加

我的问题是:当我运行这个测试应用程序,使用我的内存管理器使用的内存正确的金额。但是当我使用[new]运行相同的循环时,它会使用2.5到3倍的内存。有没有我在这里没有看到的东西,或者[新]是否会产生巨大的开销?

我使用VS 2010 Win7上。此外,我只是使用任务管理器来查看进程内存使用情况。

template<typename CLASS_TYPE> 
class MemFact 
{ 
public: 
    int m_obj_size; //size of the incoming object 
    int m_num_objs; //number of instances 
    char* m_mem; //memory block 

    MemFact(int num) : m_num_objs(num) 
    { 
    CLASS_TYPE t; 
    m_obj_size = sizeof(t); 
    m_mem = new char[m_obj_size * m_num_objs); 
    } 

    CLASS_TYPE* getInstance(int ID) 
    { 
    if(ID >= m_num_objs) return 0; 
    return (CLASS_TYPE*)(m_mem + (ID * m_obj_size)); 
    } 

    void release() { delete m_mem; m_mem = 0; } 
}; 
/*---------------------------------------------------*/ 
class test_class 
{ 
    float a,b,c,d,e,f,g,h,i,j; //10 floats 
}; 
/*---------------------------------------------------*/ 
int main() 
{ 
    int num = 10 000 000; //10 M items 
    // at this point we are using 400K memory 
    MemFact<test_class> mem_fact(num); 
    // now we're using 382MB memory 
    for(int i = 0; i < num; i++) 
    test_class* new_test = mem_fact.getInstance(i); 
    mem_fact.release(); 
    // back down to 400K 
    for(int i = 0; i < num; i++) 
    test_class* new_test = new test_class(); 
    // now we are up to 972MB memory 
} 
+4

您的程序不完整。无论如何,我们可能都不想要这一切。 – 2011-05-31 18:30:17

+0

这是什么平台? – 2011-05-31 18:35:03

+0

对不起。我试图编辑史诗格式失败,但有人编辑我之前,我想锁定我的更改。它不喜欢我把它放在那里的方式 – Veaviticus 2011-05-31 18:36:28

回答

4

内存分配的最小尺寸取决于您使用的CRT。通常这是16个字节。你的对象是12个字节宽(假设是x86),所以你可能在每个分配上至少浪费了4个字节。内存管理器也有它自己的结构来跟踪什么内存是空闲的,什么内存不是 - 这不是免费的。你的内存管理器可能非常简单(例如,一次性释放所有这些对象),这本质上会比一般情况下的更有效。

也请记住,如果你正在构建在调试模式下,调试分配器意志垫金丝雀返回分配的企图双方检测到未定义行为。这可能会将您置于16字节的边界并进入下一个 - 至少可能是32字节的分配。当您在发布模式下构建时,这将被禁用。

-2

男孩,我当然希望,没有人愿意从你的内存管理器分配任何非吊舱。或动态大小的对象。并不介意为每种类型实例化它。或者一次创建尽可能多的喜欢的东西。或者其使用寿命比MemFact长。

实际上,是一个有效的模式,称为对象池,与您的类似但不吸引。简单的答案是,operator new要求是超flexible-它的对象必须永远活着,直到delete是called-和他们的析构函数也必须被调用,而且必须有完全独立的,独立的寿命。它必须能够随时分配可变大小的对象以及任何类型的对象。您的MemFact不符合这些要求。对象池也有较少的要求,并且因为它,明显比常规new快得多,但它在所有其他方面也不完全失败。

你试着用橙色的比较几乎完全腐烂的苹果。

+0

我说过...它不需要灵活。我使用它作为2个简单的类,只要MemFact存在它们就存在。我问的是[新] ...不是我的班级。不需要粗鲁。 – Veaviticus 2011-05-31 18:41:41

+1

-1:这不是你说的,它是如何说出来的。 – 2011-05-31 19:36:51

+0

老兄,为什么这么粗鲁? – littleadv 2011-06-01 04:18:06