More example code is memory-leak free now, in particular PhysicsServerExample.

/PhysicsServerCommandProcessor
also fixed some memory issue in InverseDynamicsExample (the base class is supposed to delete collision shape memory)
This commit is contained in:
Erwin Coumans
2016-07-16 21:29:31 -07:00
parent 589fa376b3
commit c54a61b97a
9 changed files with 104 additions and 18 deletions

View File

@@ -21,6 +21,7 @@ void GraphingTexture::destroy()
m_height=0; m_height=0;
glDeleteTextures(1,(GLuint*)&m_textureId); glDeleteTextures(1,(GLuint*)&m_textureId);
m_textureId=0; m_textureId=0;
} }
bool GraphingTexture::create(int texWidth, int texHeight) bool GraphingTexture::create(int texWidth, int texHeight)

View File

@@ -675,7 +675,10 @@ struct QuickCanvas : public Common2dCanvasInterface
virtual void destroyCanvas(int canvasId) virtual void destroyCanvas(int canvasId)
{ {
btAssert(canvasId>=0); btAssert(canvasId>=0);
delete m_gt[canvasId];
m_gt[canvasId] = 0;
destroyTextureWindow(m_gw[canvasId]); destroyTextureWindow(m_gw[canvasId]);
m_gw[canvasId] = 0;
m_curNumGraphWindows--; m_curNumGraphWindows--;
} }
virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha) virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)
@@ -745,6 +748,7 @@ OpenGLExampleBrowser::~OpenGLExampleBrowser()
delete m_internalData; delete m_internalData;
gFileImporterByExtension.clear();
gAllExamples = 0; gAllExamples = 0;
} }

View File

@@ -15,7 +15,7 @@
#include "../Importers/ImportURDFDemo/ImportURDFSetup.h" #include "../Importers/ImportURDFDemo/ImportURDFSetup.h"
#include "../Importers/ImportSDFDemo/ImportSDFSetup.h" #include "../Importers/ImportSDFDemo/ImportSDFSetup.h"
#include "../Importers/ImportSTLDemo/ImportSTLSetup.h" #include "../Importers/ImportSTLDemo/ImportSTLSetup.h"
#include "LinearMath/btAlignedAllocator.h"
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@@ -49,5 +49,11 @@ int main(int argc, char* argv[])
delete exampleBrowser; delete exampleBrowser;
} }
//#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
int numBytesLeaked = btDumpMemoryLeaks();
btAssert(numBytesLeaked==0);
//#endif//BT_DEBUG_MEMORY_ALLOCATIONS
return 0; return 0;
} }

View File

@@ -73,7 +73,6 @@ class InverseDynamicsExample : public CommonMultiBodyBase
{ {
btInverseDynamicsExampleOptions m_option; btInverseDynamicsExampleOptions m_option;
btMultiBody* m_multiBody; btMultiBody* m_multiBody;
btAlignedObjectArray<btCollisionShape*> m_allocatedShapes;
btInverseDynamics::MultiBodyTree *m_inverseModel; btInverseDynamics::MultiBodyTree *m_inverseModel;
TimeSeriesCanvas* m_timeSeriesCanvas; TimeSeriesCanvas* m_timeSeriesCanvas;
public: public:
@@ -107,12 +106,6 @@ InverseDynamicsExample::InverseDynamicsExample(struct GUIHelperInterface* helper
InverseDynamicsExample::~InverseDynamicsExample() InverseDynamicsExample::~InverseDynamicsExample()
{ {
delete m_multiBody;
for (int i = 0; i < m_allocatedShapes.size(); i++)
{
delete m_allocatedShapes[i];
}
m_allocatedShapes.resize(0);
delete m_inverseModel; delete m_inverseModel;
delete m_timeSeriesCanvas; delete m_timeSeriesCanvas;
} }
@@ -175,7 +168,7 @@ void InverseDynamicsExample::initPhysics()
ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,true,u2b.getPathPrefix()); ConvertURDF2Bullet(u2b,creation, identityTrans,m_dynamicsWorld,true,u2b.getPathPrefix());
for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++) for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++)
{ {
m_allocatedShapes.push_back(u2b.getAllocatedCollisionShape(i)); m_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i));
} }
m_multiBody = creation.getBulletMultiBody(); m_multiBody = creation.getBulletMultiBody();
if (m_multiBody) if (m_multiBody)

View File

@@ -31,6 +31,10 @@ struct UrdfLinkNameMapUtil
UrdfLinkNameMapUtil():m_mb(0),m_memSerializer(0) UrdfLinkNameMapUtil():m_mb(0),m_memSerializer(0)
{ {
} }
virtual ~UrdfLinkNameMapUtil()
{
delete m_memSerializer;
}
}; };

View File

@@ -78,7 +78,6 @@ PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* shar
} }
m_data->m_commandProcessor = new PhysicsServerCommandProcessor; m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
m_data->m_commandProcessor ->createEmptyDynamicsWorld();
} }

View File

@@ -701,7 +701,16 @@ void TinyRendererVisualShapeConverter::copyCameraImageData(unsigned char* pixels
void TinyRendererVisualShapeConverter::resetAll() void TinyRendererVisualShapeConverter::resetAll()
{ {
//todo: free memory for (int i=0;i<m_data->m_swRenderInstances.size();i++)
{
TinyRendererObjectArray** ptrptr = m_data->m_swRenderInstances.getAtIndex(i);
if (ptrptr && *ptrptr)
{
TinyRendererObjectArray* ptr = *ptrptr;
delete ptr;
}
}
m_data->m_swRenderInstances.clear(); m_data->m_swRenderInstances.clear();
} }

View File

@@ -105,6 +105,27 @@ void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
} }
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
static int allocations_id[10241024];
static int allocations_bytes[10241024];
static int mynumallocs = 0;
#include <stdio.h>
int btDumpMemoryLeaks()
{
int totalLeak = 0;
for (int i=0;i<mynumallocs;i++)
{
printf("Error: leaked memory of allocation #%d (%d bytes)\n", allocations_id[i], allocations_bytes[i]);
totalLeak+=allocations_bytes[i];
}
if (totalLeak)
{
printf("Error: memory leaks: %d allocations were not freed and leaked together %d bytes\n",mynumallocs,totalLeak);
}
return totalLeak;
}
//this generic allocator provides the total allocated number of bytes //this generic allocator provides the total allocated number of bytes
#include <stdio.h> #include <stdio.h>
@@ -122,31 +143,55 @@ struct btDebugPtrMagic
void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename)
{ {
if (size==0)
{
printf("Whaat? size==0");
return 0;
}
static int allocId = 0;
void *ret; void *ret;
char *real; char *real;
// to find some particular memory leak, you could do something like this:
// if (allocId==172)
// {
// printf("catch me!\n");
// }
// if (size>1024*1024)
// {
// printf("big alloc!%d\n", size);
// }
gTotalBytesAlignedAllocs += size; gTotalBytesAlignedAllocs += size;
gNumAlignedAllocs++; gNumAlignedAllocs++;
int sz2prt = 2*sizeof(void *); int sz4prt = 4*sizeof(void *);
real = (char *)sAllocFunc(size + sz2prt + (alignment-1)); real = (char *)sAllocFunc(size + sz4prt + (alignment-1));
if (real) { if (real) {
ret = (void*) btAlignPointer(real + sz2prt, alignment); ret = (void*) btAlignPointer(real + sz4prt, alignment);
btDebugPtrMagic p; btDebugPtrMagic p;
p.vptr = ret; p.vptr = ret;
p.cptr-=sizeof(void*); p.cptr-=sizeof(void*);
*p.vptrptr = (void*)real; *p.vptrptr = (void*)real;
p.cptr-=sizeof(void*); p.cptr-=sizeof(void*);
*p.iptr = size; *p.iptr = size;
p.cptr-=sizeof(void*);
*p.iptr = allocId;
allocations_id[mynumallocs] = allocId;
allocations_bytes[mynumallocs] = size;
mynumallocs++;
} else { } else {
ret = (void *)(real);//?? ret = (void *)(real);//??
} }
printf("allocation#%d at address %x, from %s,line %d, size %d (total allocated = %d)\n",gNumAlignedAllocs,real, filename,line,size,gTotalBytesAlignedAllocs); printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n",allocId,real, filename,line,size,gTotalBytesAlignedAllocs);
allocId++;
int* ptr = (int*)ret; int* ptr = (int*)ret;
*ptr = 12; *ptr = 12;
@@ -157,19 +202,38 @@ void btAlignedFreeInternal (void* ptr,int line,char* filename)
{ {
void* real; void* real;
gNumAlignedFree++;
if (ptr) { if (ptr) {
gNumAlignedFree++;
btDebugPtrMagic p; btDebugPtrMagic p;
p.vptr = ptr; p.vptr = ptr;
p.cptr-=sizeof(void*); p.cptr-=sizeof(void*);
real = *p.vptrptr; real = *p.vptrptr;
p.cptr-=sizeof(void*); p.cptr-=sizeof(void*);
int size = *p.iptr; int size = *p.iptr;
p.cptr-=sizeof(void*);
int allocId = *p.iptr;
bool found = false;
for (int i=0;i<mynumallocs;i++)
{
if ( allocations_id[i] == allocId)
{
allocations_id[i] = allocations_id[mynumallocs-1];
allocations_bytes[i] = allocations_bytes[mynumallocs-1];
mynumallocs--;
found = true;
break;
}
}
gTotalBytesAlignedAllocs -= size; gTotalBytesAlignedAllocs -= size;
printf("free #%d at address %x, from %s,line %d, size %d (total remain = %d\n",gNumAlignedFree,real, filename,line,size, gTotalBytesAlignedAllocs); int diff = gNumAlignedAllocs-gNumAlignedFree;
printf("free %d at address %x, from %s,line %d, size %d (total remain = %d in %d non-freed allocations)\n",allocId,real, filename,line,size, gTotalBytesAlignedAllocs, diff);
sFreeFunc(real); sFreeFunc(real);
} else } else

View File

@@ -21,9 +21,15 @@ subject to the following restrictions:
///that is better portable and more predictable ///that is better portable and more predictable
#include "btScalar.h" #include "btScalar.h"
///BT_DEBUG_MEMORY_ALLOCATIONS preprocessor can be set in build system
///for regression tests to detect memory leaks
///#define BT_DEBUG_MEMORY_ALLOCATIONS 1 ///#define BT_DEBUG_MEMORY_ALLOCATIONS 1
#ifdef BT_DEBUG_MEMORY_ALLOCATIONS #ifdef BT_DEBUG_MEMORY_ALLOCATIONS
int btDumpMemoryLeaks();
#define btAlignedAlloc(a,b) \ #define btAlignedAlloc(a,b) \
btAlignedAllocInternal(a,b,__LINE__,__FILE__) btAlignedAllocInternal(a,b,__LINE__,__FILE__)