- fixed a bunch of memory leaks that will hopefully mean less overall memory requirements.

This commit is contained in:
Mark Vejvoda 2011-09-28 06:57:42 +00:00
parent 59246056bc
commit aed293bba2
11 changed files with 161 additions and 33 deletions

View File

@ -150,6 +150,17 @@ static void cleanupProcessObjects() {
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::Close(); SystemFlags::Close();
XmlIo::getInstance().cleanup();
std::map<int,Texture2D *> &crcPlayerTextureCache = CacheManager::getCachedItem< std::map<int,Texture2D *> >(GameConstants::playerTextureCacheLookupKey);
//deleteMapValues(crcPlayerTextureCache.begin(),crcPlayerTextureCache.end());
crcPlayerTextureCache.clear();
std::map<string,Texture2D *> &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map<string,Texture2D *> >(GameConstants::factionPreviewTextureCacheLookupKey);
//deleteMapValues(crcFactionPreviewTextureCache.begin(),crcFactionPreviewTextureCache.end());
crcFactionPreviewTextureCache.clear();
CacheManager::cleanupMutexes();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::SHUTDOWN_PROGRAM_MODE=true; SystemFlags::SHUTDOWN_PROGRAM_MODE=true;

View File

@ -172,6 +172,8 @@ void Faction::sortUnitsByCommandGroups() {
//printf("====== Done sorting for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size()); //printf("====== Done sorting for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size());
unsigned int originalUnitSize = units.size();
std::vector<int> unitIds; std::vector<int> unitIds;
for(unsigned int i = 0; i < units.size(); ++i) { for(unsigned int i = 0; i < units.size(); ++i) {
int unitId = units[i]->getId(); int unitId = units[i]->getId();
@ -203,6 +205,7 @@ void Faction::sortUnitsByCommandGroups() {
units.push_back(this->findUnit(unitId)); units.push_back(this->findUnit(unitId));
} }
assert(originalUnitSize == units.size());
} }
// ===================================================== // =====================================================
@ -392,6 +395,12 @@ Faction::~Faction() {
workerThread = NULL; workerThread = NULL;
} }
MutexSafeWrapper safeMutex(unitsMutex,string(__FILE__) + "_" + intToStr(__LINE__));
deleteValues(units.begin(), units.end());
units.clear();
safeMutex.ReleaseLock();
//delete texture; //delete texture;
texture = NULL; texture = NULL;
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -402,6 +411,26 @@ Faction::~Faction() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
void Faction::end() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(workerThread != NULL) {
workerThread->signalQuit();
if(workerThread->shutdownAndWait() == true) {
delete workerThread;
}
workerThread = NULL;
}
MutexSafeWrapper safeMutex(unitsMutex,string(__FILE__) + "_" + intToStr(__LINE__));
deleteValues(units.begin(), units.end());
units.clear();
safeMutex.ReleaseLock();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
Unit * Faction::getUnit(int i) const { Unit * Faction::getUnit(int i) const {
Unit *result = units[i]; Unit *result = units[i];
return result; return result;
@ -474,24 +503,6 @@ void Faction::init(
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
void Faction::end() {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(workerThread != NULL) {
workerThread->signalQuit();
if(workerThread->shutdownAndWait() == true) {
delete workerThread;
}
workerThread = NULL;
}
MutexSafeWrapper safeMutex(unitsMutex,string(__FILE__) + "_" + intToStr(__LINE__));
deleteValues(units.begin(), units.end());
safeMutex.ReleaseLock();
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
// ================== get ================== // ================== get ==================
const Resource *Faction::getResource(const ResourceType *rt) const{ const Resource *Faction::getResource(const ResourceType *rt) const{

View File

@ -40,7 +40,17 @@ namespace Glest{ namespace Game{
const int UnitPathBasic::maxBlockCount= GameConstants::updateFps / 2; const int UnitPathBasic::maxBlockCount= GameConstants::updateFps / 2;
#ifdef LEAK_CHECK_UNITS
std::map<UnitPathBasic *,bool> UnitPathBasic::mapMemoryList;
std::map<Unit *,bool> Unit::mapMemoryList;
std::map<UnitPathInterface *,int> Unit::mapMemoryList2;
#endif
UnitPathBasic::UnitPathBasic() : UnitPathInterface() { UnitPathBasic::UnitPathBasic() : UnitPathInterface() {
#ifdef LEAK_CHECK_UNITS
UnitPathBasic::mapMemoryList[this]=true;
#endif
this->blockCount = 0; this->blockCount = 0;
this->pathQueue.clear(); this->pathQueue.clear();
this->lastPathCacheQueue.clear(); this->lastPathCacheQueue.clear();
@ -52,8 +62,26 @@ UnitPathBasic::~UnitPathBasic() {
this->pathQueue.clear(); this->pathQueue.clear();
this->lastPathCacheQueue.clear(); this->lastPathCacheQueue.clear();
this->map = NULL; this->map = NULL;
#ifdef LEAK_CHECK_UNITS
UnitPathBasic::mapMemoryList.erase(this);
#endif
} }
#ifdef LEAK_CHECK_UNITS
void UnitPathBasic::dumpMemoryList() {
printf("===== START report of Unfreed UnitPathBasic pointers =====\n");
for(std::map<UnitPathBasic *,bool>::iterator iterMap = UnitPathBasic::mapMemoryList.begin();
iterMap != UnitPathBasic::mapMemoryList.end(); ++iterMap) {
printf("************** ==> Unfreed UnitPathBasic pointer [%p]\n",iterMap->first);
if(Unit::mapMemoryList2.find(iterMap->first) != Unit::mapMemoryList2.end()) {
printf("Found owner unit id [%d]\n",Unit::mapMemoryList2[iterMap->first]);
}
}
}
#endif
bool UnitPathBasic::isEmpty() const { bool UnitPathBasic::isEmpty() const {
return pathQueue.empty(); return pathQueue.empty();
} }
@ -249,6 +277,10 @@ const int Unit::invalidId= -1;
Game *Unit::game = NULL; Game *Unit::game = NULL;
Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) { Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) {
#ifdef LEAK_CHECK_UNITS
Unit::mapMemoryList[this]=true;
#endif
lastSynchDataString=""; lastSynchDataString="";
modelFacing = CardinalDir::NORTH; modelFacing = CardinalDir::NORTH;
lastStuckFrame = 0; lastStuckFrame = 0;
@ -263,6 +295,8 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType
rotationZ=.0f; rotationZ=.0f;
rotationX=.0f; rotationX=.0f;
this->unitPath = unitpath;
this->unitPath->setMap(map);
RandomGen random; RandomGen random;
@ -270,8 +304,6 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType
throw runtime_error("#2 Invalid path position = " + pos.getString()); throw runtime_error("#2 Invalid path position = " + pos.getString());
} }
this->unitPath = unitpath;
this->unitPath->setMap(map);
this->pos=pos; this->pos=pos;
this->type=type; this->type=type;
this->faction=faction; this->faction=faction;
@ -402,6 +434,10 @@ Unit::~Unit() {
delete currentAttackBoostOriginatorEffect.currentAppliedEffect; delete currentAttackBoostOriginatorEffect.currentAppliedEffect;
currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL;
#ifdef LEAK_CHECK_UNITS
Unit::mapMemoryList2[this->unitPath] = this->getId();
#endif
delete this->unitPath; delete this->unitPath;
this->unitPath = NULL; this->unitPath = NULL;
@ -410,8 +446,22 @@ Unit::~Unit() {
//MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); //MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));
//deletedUnits[this]=true; //deletedUnits[this]=true;
#ifdef LEAK_CHECK_UNITS
Unit::mapMemoryList.erase(this);
#endif
} }
#ifdef LEAK_CHECK_UNITS
void Unit::dumpMemoryList() {
printf("===== START report of Unfreed Unit pointers =====\n");
for(std::map<Unit *,bool>::iterator iterMap = Unit::mapMemoryList.begin();
iterMap != Unit::mapMemoryList.end(); ++iterMap) {
printf("************** ==> Unfreed Unit pointer [%p]\n",iterMap->first);
}
}
#endif
//bool Unit::isUnitDeleted(void *unit) { //bool Unit::isUnitDeleted(void *unit) {
// bool result = false; // bool result = false;
// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); // MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__));

View File

@ -20,6 +20,8 @@
#include <vector> #include <vector>
#include "leak_dumper.h" #include "leak_dumper.h"
//#define LEAK_CHECK_UNITS
namespace Glest { namespace Game { namespace Glest { namespace Game {
using Shared::Graphics::ParticleSystem; using Shared::Graphics::ParticleSystem;
@ -102,6 +104,8 @@ public:
class UnitPathInterface { class UnitPathInterface {
public: public:
UnitPathInterface() {}
virtual ~UnitPathInterface() {}
virtual bool isBlocked() const = 0; virtual bool isBlocked() const = 0;
virtual bool isEmpty() const = 0; virtual bool isEmpty() const = 0;
@ -128,6 +132,10 @@ private:
static const int maxBlockCount; static const int maxBlockCount;
Map *map; Map *map;
#ifdef LEAK_CHECK_UNITS
static std::map<UnitPathBasic *,bool> mapMemoryList;
#endif
private: private:
int blockCount; int blockCount;
vector<Vec2i> pathQueue; vector<Vec2i> pathQueue;
@ -136,6 +144,11 @@ private:
public: public:
UnitPathBasic(); UnitPathBasic();
virtual ~UnitPathBasic(); virtual ~UnitPathBasic();
#ifdef LEAK_CHECK_UNITS
static void dumpMemoryList();
#endif
virtual bool isBlocked() const; virtual bool isBlocked() const;
virtual bool isEmpty() const; virtual bool isEmpty() const;
virtual bool isStuck() const; virtual bool isStuck() const;
@ -175,7 +188,7 @@ private:
Map *map; Map *map;
public: public:
UnitPath() : blockCount(0), map(NULL) {} /**< Construct path object */ UnitPath() : UnitPathInterface(), blockCount(0), map(NULL) {} /**< Construct path object */
virtual bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */ virtual bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */
virtual bool isEmpty() const {return list<Vec2i>::empty();} /**< is path empty */ virtual bool isEmpty() const {return list<Vec2i>::empty();} /**< is path empty */
virtual bool isStuck() const {return false; } virtual bool isStuck() const {return false; }
@ -262,12 +275,21 @@ private:
typedef list<UnitObserver*> Observers; typedef list<UnitObserver*> Observers;
typedef vector<UnitParticleSystem*> UnitParticleSystems; typedef vector<UnitParticleSystem*> UnitParticleSystems;
#ifdef LEAK_CHECK_UNITS
static std::map<Unit *,bool> mapMemoryList;
#endif
public: public:
static const float speedDivider; static const float speedDivider;
static const int maxDeadCount; static const int maxDeadCount;
static const float highlightTime; static const float highlightTime;
static const int invalidId; static const int invalidId;
#ifdef LEAK_CHECK_UNITS
static std::map<UnitPathInterface *,int> mapMemoryList2;
static void dumpMemoryList();
#endif
private: private:
const int id; const int id;
int hp; int hp;

View File

@ -102,6 +102,12 @@ World::~World() {
} }
factions.clear(); factions.clear();
#ifdef LEAK_CHECK_UNITS
printf("%s::%s\n",__FILE__,__FUNCTION__);
Unit::dumpMemoryList();
UnitPathBasic::dumpMemoryList();
#endif
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
delete techTree; delete techTree;
@ -147,6 +153,12 @@ void World::end(){
} }
factions.clear(); factions.clear();
#ifdef LEAK_CHECK_UNITS
printf("%s::%s\n",__FILE__,__FUNCTION__);
Unit::dumpMemoryList();
UnitPathBasic::dumpMemoryList();
#endif
fogOfWarOverride = false; fogOfWarOverride = false;
map.end(); map.end();

View File

@ -93,7 +93,7 @@ protected:
public: public:
CacheManager() { } CacheManager() { }
~CacheManager() { static void cleanupMutexes() {
for(std::map<string, Mutex *>::iterator iterMap = itemCacheMutexList.begin(); for(std::map<string, Mutex *>::iterator iterMap = itemCacheMutexList.begin();
iterMap != itemCacheMutexList.end(); iterMap++) { iterMap != itemCacheMutexList.end(); iterMap++) {
delete iterMap->second; delete iterMap->second;
@ -101,6 +101,9 @@ public:
} }
itemCacheMutexList.clear(); itemCacheMutexList.clear();
} }
~CacheManager() {
CacheManager::cleanupMutexes();
}
template <typename T> template <typename T>
static void setCachedItem(string cacheKey, const T value) { static void setCachedItem(string cacheKey, const T value) {

View File

@ -133,6 +133,7 @@ public:
static CURL *initHTTP(); static CURL *initHTTP();
static void cleanupHTTP(CURL **handle,bool globalCleanup=false); static void cleanupHTTP(CURL **handle,bool globalCleanup=false);
static void globalCleanupHTTP();
static bool getThreadedLoggerRunning(); static bool getThreadedLoggerRunning();
static std::size_t getLogEntryBufferCount(); static std::size_t getLogEntryBufferCount();

View File

@ -53,6 +53,8 @@ private:
public: public:
static XmlIo &getInstance(); static XmlIo &getInstance();
~XmlIo(); ~XmlIo();
void cleanup();
XmlNode *load(const string &path, std::map<string,string> mapTagReplacementValues); XmlNode *load(const string &path, std::map<string,string> mapTagReplacementValues);
void save(const string &path, const XmlNode *node); void save(const string &path, const XmlNode *node);
}; };

View File

@ -83,6 +83,9 @@ ParticleSystem::~ParticleSystem(){
//delete [] particles; //delete [] particles;
particles.clear(); particles.clear();
delete particleObserver;
particleObserver = NULL;
} }
// =============== VIRTUAL ====================== // =============== VIRTUAL ======================

View File

@ -271,17 +271,21 @@ SystemFlags::SystemFlags() {
} }
void SystemFlags::globalCleanupHTTP() {
if(SystemFlags::curl_global_init_called == true) {
SystemFlags::curl_global_init_called = false;
curl_global_cleanup();
//printf("In [%s::%s Line %d] curl_global_cleanup called\n",__FILE__,__FUNCTION__,__LINE__);
}
}
void SystemFlags::cleanupHTTP(CURL **handle, bool globalCleanup) { void SystemFlags::cleanupHTTP(CURL **handle, bool globalCleanup) {
if(handle != NULL && *handle != NULL) { if(handle != NULL && *handle != NULL) {
curl_easy_cleanup(*handle); curl_easy_cleanup(*handle);
*handle = NULL; *handle = NULL;
if(globalCleanup == true) { if(globalCleanup == true) {
if(SystemFlags::curl_global_init_called == true) { SystemFlags::globalCleanupHTTP();
SystemFlags::curl_global_init_called = false;
curl_global_cleanup();
//printf("In [%s::%s Line %d] curl_global_cleanup called\n",__FILE__,__FUNCTION__,__LINE__);
}
} }
} }
} }
@ -297,9 +301,7 @@ SystemFlags::~SystemFlags() {
curl_handle = NULL; curl_handle = NULL;
} }
if(SystemFlags::curl_global_init_called == true) { if(SystemFlags::curl_global_init_called == true) {
SystemFlags::curl_global_init_called = false; SystemFlags::globalCleanupHTTP();
curl_global_cleanup();
//printf("In [%s::%s Line %d] curl_global_cleanup called\n",__FILE__,__FUNCTION__,__LINE__);
} }
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -373,6 +375,8 @@ void SystemFlags::Close() {
} }
} }
SystemFlags::globalCleanupHTTP();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }

View File

@ -65,6 +65,8 @@ bool XmlIo::initialized= false;
XmlIo::XmlIo() { XmlIo::XmlIo() {
try{ try{
XMLPlatformUtils::Initialize(); XMLPlatformUtils::Initialize();
XmlIo::initialized= true;
} }
catch(const XMLException &e){ catch(const XMLException &e){
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error initializing XML system, msg %s\n",__FILE__,__FUNCTION__,__LINE__,e.getMessage()); SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error initializing XML system, msg %s\n",__FILE__,__FUNCTION__,__LINE__,e.getMessage());
@ -88,9 +90,16 @@ XmlIo &XmlIo::getInstance(){
return XmlIo; return XmlIo;
} }
XmlIo::~XmlIo(){ void XmlIo::cleanup() {
if(XmlIo::initialized == true) {
XmlIo::initialized= false;
XMLPlatformUtils::Terminate(); XMLPlatformUtils::Terminate();
} }
}
XmlIo::~XmlIo() {
cleanup();
}
XmlNode *XmlIo::load(const string &path, std::map<string,string> mapTagReplacementValues) { XmlNode *XmlIo::load(const string &path, std::map<string,string> mapTagReplacementValues) {