2012-07-26 46 views
2

我正在使用debug_new来查找内存泄漏。我正在删除我的对象,而debug_new没有显示我泄漏它们的任何痕迹。内存使用量增加。释放内存不被重用

我读过内存碎片的几个线程。但我仍然困惑。在这一点上,我正在测试我的框架,我正在做一个简单的测试。我创建了一个新的对象,像这样:

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space)){ 
    artemis::Entity& e = world->createEntity(); 
    e.addComponent(new PositionComponent(posX,posY)); 
    e.addComponent(new MovementComponent(500,0)); 
    e.addComponent(new SpriteComponent(TextureManager::getInstance().getTexture("bullet.png"))); 
    e.addComponent(new ColliderComponent(10,10)); 
    e.refresh(); 
    e.setGroup("BULLET"); 
} 

这些“组件”在一个名为“EntityManager的”,这重用实体对象,但破坏的组件当实体是发回的“池子”的经理进行管理。 我测试过了,只有在池中没有可用实体时才会创建新实体。

正如你可以看到上面的代码。在这个简单的测试中,模式是相同的。然而,分配器使用新的内存,而不是重复使用任何以前使用的内存。每空白吧创造几千次(每1/60帧),使我的记忆力进入2吉格频谱。这些组件甚至没那么大。例如:

class ColliderComponent : public artemis::Component{ 

    public: 
    int width,height,collidionsId; 

    ColliderComponent(int width, int height){ 
     this->width = width; 
     this->height = height; 
    } 
}; 

到目前为止,大多数组件都是简单的“集合”。它们非常轻便。它肯定应该重用一些先前分配/释放的内存。但它没有。

也许我错过了一些东西。有没有人对可能发生的事情有不同的看法?有没有好的(免费)内存分析器? 如果这不是因为我的组件,这个缺陷必须在别的地方。我现在根本看不到它,至少可以说是令人沮丧的。

编辑: 它看起来像我俯瞰这造成了重大泄漏的不同部分。这显然是我自己愚蠢的错误。

这是罪魁祸首: e.setGroup(“BULLET”);

“子弹”被保存为指针(我应该重新设计这种)和实体ID的指数被重写指向现有的字符串。我不知道为什么我忽略了这一点,但我的内存分配现在是稳定的!

我可以使用智能指针,但到目前为止,我已经从这个学习了很多!我觉得我已经取得了一些成绩= d

+0

你如何衡量使用的内存? – Nick 2012-07-26 00:40:37

+0

这可能听起来很愚蠢。但我只是检查taskmanager。但即使如此,这个简单的应用程序不应该超过1演出。不在它目前的状态。 – Sidar 2012-07-26 00:42:42

+1

这是使用哑指针不明智的原因之一。 – 2012-07-26 00:44:28

回答

1

我在ColliderComponent中看不到超载的new运算符,这导致我相信你总是从堆中分配,并将内存给予你的EntityManager。这肯定会看起来像一个泄漏,只要你的EntityManager遭到破坏就会消失。

编辑:我更了解你的代码是如何工作的吧。组件没有被你的EntityManager缓存,只有Entity是。

+0

那么你有什么建议?因为我在这里真的很茫然。 – Sidar 2012-07-26 09:58:56

+0

@Sidar:你是怎么想到EntityManager会在'EntityManager'中被重用的?是否有一个接口可以将组件从池中取出? – jxh 2012-07-26 10:03:47

+0

我已更新我的代码。 – Sidar 2012-07-26 10:11:24

0

你说你正在使用任务管理器来评估内存消耗 - 大多数存储经理们无法立即返回释放的内存给操作系统(这是一个相当昂贵的操作),但保留内存可用于应用程序本身。因此,您的应用程序的内存管理器(它是C++运行时的一部分)将标记为您释放的空闲块,并且稍后可以在内存的另一个请求进入时重用该块。

这具有性能优势,因为运行时内存管理器不会经常呼叫操作系统释放内存然后重新获取内存。

+0

我明白这一点。然而。它看起来像内存不会被重用。它超过了2gig的标记,并继续前进。这个例子不应该发生。我已经看到“重量级”的程序甚至不超过500MB。 – Sidar 2012-07-26 00:58:18