我正在使用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”的管理器中进行管理,该管理器重用Entity对象,但在实体发送回“池”时销毁组件。 我已经对此进行了测试,如果池中没有可用的实体,则只会生成新的实体。
正如您在上面的代码中看到的那样。在这个简单的测试中,模式是相同的。然而,分配器继续使用新内存而不是重用任何以前使用的内存。每个空格键击中创建几千个(每帧每1/60帧)导致我的记忆进入2 gig频谱。组件甚至不是那么大。例如:
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 :(得分:1)
我在new
中没有看到重载的ColliderComponent
运算符,这让我相信你总是从堆中分配,并将内存提供给EntityManager
。这肯定看起来像是一个泄漏,一旦你的EntityManager
被破坏就会消失。
修改:我更了解您的代码现在如何运作。您的EntityManager
不会缓存组件,只有Entity
是。
答案 1 :(得分:0)
您说您正在使用任务管理器来评估内存消耗 - 大多数内存管理器不会立即将释放的内存返回给操作系统(这是一项相当昂贵的操作),但保留内存可供应用程序本身使用。因此,应用程序的内存管理器(它是C ++运行时的一部分)会将您释放的块标记为空闲,并且可以在以后再发出另一个内存请求时重复使用它。
这具有性能优势,因为运行时的内存管理器不必经常调用操作系统来释放然后重新获取内存。