2012-07-26 98 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