2012-07-26 3 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; 
    } 
}; 

대부분의 구성 요소는 지금까지 int의 단순한 "모음"입니다. 그들은 꽤 가볍습니다. 이전에 할당/해제 된 메모리 중 일부를 확실히 재사용해야합니다. 그러나 그것은 단지하지 않습니다.

아마도 나는 뭔가를 놓치고 있습니다. 아무도 무슨 일이 벌어 질지에 대해 다른 생각을 갖고 있습니까? 그리고 좋은 (무료) 메모리 프로파일 러가 있습니까? 구성 요소가 없기 때문에 결함이 다른 위치에 있어야합니다. 나는이 시점에서 그것을 단순히 볼 수 없으며 가장 적은 것을 말하면 좌절감을 느낍니다.

편집 : 큰 누출을 일으킨 다른 부분을 간과 한 것처럼 보입니다. 이것은 나 자신에 의해 명백하게 멍청한 잘못이었다.

이것은 범인입니다 : e.setGroup ("BULLET");

"BULLET"이 (다시 디자인해야 함) 포인터로 저장되며 엔티티 ID의 인덱스에서 기존 문자열에 대한 포인터를 무시하고 있습니다. 왜 내가 이것을 간과했는지 모르지만 내 메모리 할당은 이제 안정적입니다!

나는 스마트 포인터를 사용할 수 있었지만, 지금까지 이걸 많이 배웠습니다! 내가 뭔가를 얻은 것 같아 = D

+0

어떻게 메모리 사용량을 측정하고 있습니까? – Nick

+0

어리석게 들릴 수도 있습니다. 그러나 나는 taskmanager를 점검하고있다. 그러나이 간단한 애플리케이션은 1 기가 이상을 초과해서는 안됩니다. 현재 상태가 아닙니다. – Sidar

+1

이것은 바보 포인터를 사용하는 것이 현명한 이유 중 하나입니다. –

답변

1

에 오버로드 된 new 연산자가 표시되지 않아 항상 힙에서 할당하고 있음을 알게되고 EntityManager에 메모리를 제공합니다. 이것은 확실히 누수처럼 보일 것이며, EntityManager이 파괴되면 사라질 것입니다.

편집 : 이제 코드 작동 방식에 대해 더 잘 이해합니다.구성 요소는 EntityManager에 의해 캐시되지 않으며 Entity 만 있습니다.

+0

그렇다면 무엇을 제안합니까? 왜냐하면 나는 정말로 여기 잃었습니다. – Sidar

+0

@Sidar : Entity 객체가'EntityManager'에서 재사용 될 것이라고 어떻게 상상 했습니까? 풀에서 구성 요소를 꺼내기위한 인터페이스가 있었습니까? – jxh

+0

코드를 업데이트했습니다. – Sidar

0

당신은 메모리 사용량을 평가하기 위해 작업 관리자를 사용한다고합니다. 대부분의 메모리 관리자는 즉각적으로 해제 된 메모리를 운영 체제로 반환하지 않지만 (상당히 비싼 작업 임) 응용 프로그램 자체의 사용을 위해 사용 가능한 메모리. 따라서 응용 프로그램의 메모리 관리자 (C++ 런타임의 일부)는 해제 한 블록을 무료로 표시하고 나중에 메모리에 대한 다른 요청이 들어올 때 다시 사용할 수 있습니다.

이것은 런타임의 이점 메모리 관리자는 OS를 호출 한 다음 메모리를 다시 가져 오도록 끊임없이 호출 할 필요가 없습니다.

+0

그 점을 이해합니다. 하나. 메모리가 결코 재사용되지 않는 것처럼 보입니다. 그것은 2gig 표를 초과하고 계속 가고 있었다. 이 예제에서는 발생하지 않아야합니다. 나는 "무거운"프로그램이 500MB를 초월하지 못하는 것을 보았습니다. – Sidar

관련 문제