From 04d03d10beb1628ee4ff90e78de206290dbc7547 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Sat, 16 Jun 2018 09:37:53 -0700 Subject: [PATCH] Fix memory leak due to batchRayCast never deleting the btTaskScheduler. (and issue with TaskScheduler/btTaskScheduler.cpp, add JobQueue::exit, call it first, since it uses the m_threadSupport which was deleted before the destrucor was called. Use a hashmap to store user timers, to avoid allocating many identical strings. --- .../PhysicsClientSharedMemory.cpp | 27 ++++++++++++++++--- examples/SharedMemory/PhysicsDirect.cpp | 24 ++++++++++++----- examples/SharedMemory/PhysicsLoopBack.cpp | 8 ++++++ examples/SharedMemory/PhysicsLoopBack.h | 3 +++ .../PhysicsServerCommandProcessor.cpp | 16 +++++++---- .../TaskScheduler/btTaskScheduler.cpp | 16 +++++++++-- 6 files changed, 77 insertions(+), 17 deletions(-) diff --git a/examples/SharedMemory/PhysicsClientSharedMemory.cpp b/examples/SharedMemory/PhysicsClientSharedMemory.cpp index 63cccdf7e..131cc5d5f 100644 --- a/examples/SharedMemory/PhysicsClientSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsClientSharedMemory.cpp @@ -49,7 +49,7 @@ struct PhysicsClientSharedMemoryInternalData { SharedMemoryBlock* m_testBlock1; btAlignedObjectArray m_profileTimings; - btAlignedObjectArray m_profileTimingStrings; + btHashMap m_profileTimingStringArray; btHashMap m_bodyJointMap; btHashMap m_userConstraintInfoMap; @@ -221,6 +221,16 @@ PhysicsClientSharedMemory::~PhysicsClientSharedMemory() { } resetData(); + for (int i=0;im_profileTimingStringArray.size();i++) + { + std::string** str = m_data->m_profileTimingStringArray.getAtIndex(i); + if (str) + { + delete *str; + } + } + m_data->m_profileTimingStringArray.clear(); + if (m_data->m_ownsSharedMemory) { delete m_data->m_sharedMemory; @@ -239,6 +249,8 @@ void PhysicsClientSharedMemory::removeCachedBody(int bodyUniqueId) } void PhysicsClientSharedMemory::resetData() { + + m_data->m_debugLinesFrom.clear(); m_data->m_debugLinesTo.clear(); m_data->m_debugLinesColor.clear(); @@ -1916,10 +1928,17 @@ void PhysicsClientSharedMemory::getUserDataInfo(int bodyUniqueId, int linkIndex, void PhysicsClientSharedMemory::pushProfileTiming(const char* timingName) { - std::string* str = new std::string(timingName); - m_data->m_profileTimingStrings.push_back(str); + std::string** strPtr = m_data->m_profileTimingStringArray[timingName]; + std::string* str = 0; + if (strPtr) + { + str = *strPtr; + } else + { + str = new std::string(timingName); + m_data->m_profileTimingStringArray.insert(timingName,str); + } m_data->m_profileTimings.push_back(new CProfileSample(str->c_str())); - } diff --git a/examples/SharedMemory/PhysicsDirect.cpp b/examples/SharedMemory/PhysicsDirect.cpp index aba9264ed..24fb40a29 100644 --- a/examples/SharedMemory/PhysicsDirect.cpp +++ b/examples/SharedMemory/PhysicsDirect.cpp @@ -62,7 +62,7 @@ struct PhysicsDirectInternalData btHashMap m_userConstraintInfoMap; btAlignedObjectArray m_profileTimings; - btAlignedObjectArray m_profileTimingStrings; + btHashMap m_profileTimingStringArray; char m_bulletStreamDataServerToClient[SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE]; btAlignedObjectArray m_cachedMassMatrix; @@ -117,11 +117,15 @@ PhysicsDirect::PhysicsDirect(PhysicsCommandProcessorInterface* physSdk, bool pas PhysicsDirect::~PhysicsDirect() { - for (int i=0;im_profileTimingStrings.size();i++) + for (int i=0;im_profileTimingStringArray.size();i++) { - delete m_data->m_profileTimingStrings[i]; + std::string** str = m_data->m_profileTimingStringArray.getAtIndex(i); + if (str) + { + delete *str; + } } - m_data->m_profileTimingStrings.clear(); + m_data->m_profileTimingStringArray.clear(); if (m_data->m_commandProcessor->isConnected()) { @@ -1567,8 +1571,16 @@ void PhysicsDirect::getUserDataInfo(int bodyUniqueId, int linkIndex, int userDat void PhysicsDirect::pushProfileTiming(const char* timingName) { - std::string* str = new std::string(timingName); - m_data->m_profileTimingStrings.push_back(str); + std::string** strPtr = m_data->m_profileTimingStringArray[timingName]; + std::string* str = 0; + if (strPtr) + { + str = *strPtr; + } else + { + str = new std::string(timingName); + m_data->m_profileTimingStringArray.insert(timingName,str); + } m_data->m_profileTimings.push_back(new CProfileSample(str->c_str())); } diff --git a/examples/SharedMemory/PhysicsLoopBack.cpp b/examples/SharedMemory/PhysicsLoopBack.cpp index 07e5e2ca3..4a4b00d70 100644 --- a/examples/SharedMemory/PhysicsLoopBack.cpp +++ b/examples/SharedMemory/PhysicsLoopBack.cpp @@ -247,3 +247,11 @@ void PhysicsLoopBack::getUserDataInfo(int bodyUniqueId, int linkIndex, int userD m_data->m_physicsClient->getUserDataInfo(bodyUniqueId, linkIndex, userDataIndex, keyOut, userDataIdOut); } +void PhysicsLoopBack::pushProfileTiming(const char* timingName) +{ + m_data->m_physicsClient->pushProfileTiming(timingName); +} +void PhysicsLoopBack::popProfileTiming() +{ + m_data->m_physicsClient->popProfileTiming(); +} \ No newline at end of file diff --git a/examples/SharedMemory/PhysicsLoopBack.h b/examples/SharedMemory/PhysicsLoopBack.h index 5824431a5..e18fa22f8 100644 --- a/examples/SharedMemory/PhysicsLoopBack.h +++ b/examples/SharedMemory/PhysicsLoopBack.h @@ -93,6 +93,9 @@ public: virtual int getCachedUserDataId(int bodyUniqueId, int linkIndex, const char *key) const; virtual int getNumUserData(int bodyUniqueId, int linkIndex) const; virtual void getUserDataInfo(int bodyUniqueId, int linkIndex, int userDataIndex, const char **keyOut, int *userDataIdOut) const; + + virtual void pushProfileTiming(const char* timingName); + virtual void popProfileTiming(); }; #endif //PHYSICS_LOOP_BACK_H diff --git a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp index 56a083a61..0f27342b8 100644 --- a/examples/SharedMemory/PhysicsServerCommandProcessor.cpp +++ b/examples/SharedMemory/PhysicsServerCommandProcessor.cpp @@ -1659,6 +1659,8 @@ struct PhysicsServerCommandProcessorInternalData b3HashMap m_profileEvents; b3HashMap m_cachedVUrdfisualShapes; + btITaskScheduler* m_scheduler; + PhysicsServerCommandProcessorInternalData(PhysicsCommandProcessorInterface* proc) :m_pluginManager(proc), m_useRealTimeSimulation(false), @@ -1686,7 +1688,8 @@ struct PhysicsServerCommandProcessorInternalData m_pickedBody(0), m_pickedConstraint(0), m_pickingMultiBodyPoint2Point(0), - m_pdControlPlugin(-1) + m_pdControlPlugin(-1), + m_scheduler(0) { { @@ -1782,11 +1785,11 @@ PhysicsServerCommandProcessor::PhysicsServerCommandProcessor() #ifdef BT_THREADSAFE if (btGetTaskScheduler() == 0) { - btITaskScheduler *scheduler = btCreateDefaultTaskScheduler(); - if (scheduler == 0) { - scheduler = btGetSequentialTaskScheduler(); + m_data->m_scheduler = btCreateDefaultTaskScheduler(); + if (m_data->m_scheduler == 0) { + m_data->m_scheduler = btGetSequentialTaskScheduler(); } - btSetTaskScheduler(scheduler); + btSetTaskScheduler(m_data->m_scheduler); } #endif //BT_THREADSAFE } @@ -1804,6 +1807,9 @@ PhysicsServerCommandProcessor::~PhysicsServerCommandProcessor() char* event = *m_data->m_profileEvents.getAtIndex(i); delete[] event; } + if (m_data->m_scheduler) + delete m_data->m_scheduler; + delete m_data; } diff --git a/src/LinearMath/TaskScheduler/btTaskScheduler.cpp b/src/LinearMath/TaskScheduler/btTaskScheduler.cpp index 4643bbee8..49510d166 100644 --- a/src/LinearMath/TaskScheduler/btTaskScheduler.cpp +++ b/src/LinearMath/TaskScheduler/btTaskScheduler.cpp @@ -209,13 +209,19 @@ public: } ~JobQueue() { - freeJobMem(); + exit(); + } + void exit() + { + freeJobMem(); if (m_queueLock && m_threadSupport) { m_threadSupport->deleteCriticalSection(m_queueLock); m_queueLock = NULL; + m_threadSupport = 0; } - } + } + void init(btThreadSupportInterface* threadSup, btAlignedObjectArray* contextArray) { m_threadSupport = threadSup; @@ -448,6 +454,12 @@ public: virtual ~btTaskSchedulerDefault() { waitForWorkersToSleep(); + + for ( int i = 0; i < m_jobQueues.size(); ++i ) + { + m_jobQueues[i].exit(); + } + if (m_threadSupport) { delete m_threadSupport;