Not logged in, Join Here! or Log In Below:  
 
News Articles Search    
 

 Home / General Programming / Memory loss... Account Manager
 
Archive Notice: This thread is old and no longer active. It is here for reference purposes. This thread was created on an older version of the flipcode forums, before the site closed in 2005. Please keep that in mind as you view this thread, as many of the topics and opinions may be outdated.
 
mrmcoleman

May 19, 2005, 07:05 PM

I have tracked down a rather annoying memory leakage bug to these lines...

  1.  
  2. // There are no dead particles to reactivate so we will make
  3. // another one if there is enough space on the ParticleList
  4. if(ParticleList.size() <= MaxParticles)
  5. {
  6.         Particle newParticle;
  7.         InitialiseParticle(NewParticlePosition, &newParticle);
  8.         ParticleList.push_back(newParticle);
  9. }
  10. else
  11. {
  12.         // There is no space for any more particles so we don't do anything
  13. }
  14.  


This code is basically looped every time new particles have to be added to the particle system. I'm assuming that the problem is something to do with passing a pointer to static memory, buts it's been a long day and I can't see the problem right off the bat.

Here's the InitialiseParticleMethod incase it helps (it's a bit messy ;()...

  1.  
  2. void ScreenEntityParticleSystem::InitialiseParticle(D3DXVECTOR2 CurrentPosition, Particle* DeadParticle)
  3. {
  4.         // Update the position
  5.         DeadParticle->CurrentPosition = CurrentPosition;
  6.        
  7.         // Increment the particle count
  8.         ++CurrentParticleCount;
  9.        
  10.         // Tell the particle that it is alive!
  11.         DeadParticle->Dead = false;
  12.  
  13.         // Set the intial velocity, colour, lifetime and alpha decay in accordance with the type of effect being created
  14.         if((Flags & PARTICLE_SMOKE) > 0)
  15.         {
  16.                 // ************** VELOCITY ****
  17.                 DeadParticle->CurrentVelocity.y = - 60.0f;
  18.                 DeadParticle->CurrentVelocity.x = 10.0f - floatRand(20.0f);
  19.  
  20.                 // ************** COLOUR ****
  21.                 // Define each colour element (plus the alpha)
  22.                 int r, g, b, a, random;
  23.  
  24.                 // ********** BOUNDING BOX INTERACTION ******
  25.                 DeadParticle->Mass = true;
  26.  
  27.                 r = 255;        // Red
  28.                 g = 240;        // Green
  29.                 b = 230;        // Blue
  30.                 a = 90;         // Alpha
  31.  
  32.                 // Set the colour
  33.                 DeadParticle->Colour = D3DCOLOR_RGBA(r, g, b, a);
  34.                
  35.                 // ************** LIFETIME ****
  36.                 // Alter the life time by 0.5 either way
  37.                 DeadParticle->LifeTime = 2.5f + floatRand(2.f);
  38.         }
  39.         else if((Flags & PARTICLE_DUST) > 0)
  40.         {
  41.                 // ************** VELOCITY ****
  42.                 DeadParticle->CurrentVelocity.y = 0.0f;
  43.  
  44.                 DeadParticle->CurrentVelocity.x = 0.0f;
  45.                
  46.                 // ************** COLOUR ****
  47.                 // Define each colour element (plus the alpha)
  48.                 int r, g, b, a;
  49.  
  50.                 // ********** BOUNDING BOX INTERACTION ******
  51.                 DeadParticle->Mass = true;
  52.  
  53.                 r = 230;                // Red
  54.                 g = 210;                // Green
  55.                 b = 160;                // Blue
  56.                 a = 50;                 // Alpha
  57.  
  58.                 // Set the colour
  59.                 DeadParticle->Colour = D3DCOLOR_RGBA(r, g, b, a);
  60.                
  61.                 // ************** LIFETIME ****
  62.                 // Alter the life time by 0.5 either way
  63.                 DeadParticle->LifeTime = 1.5f + floatRand(1.0f);
  64.         }
  65.         else
  66.         {
  67.                 DXTRACE_MSG("Particle system is of an invalid type or flag not set");
  68.                 PostQuitMessage(0);
  69.         }
  70.  
  71.         // Set the start time of the particle
  72.         DeadParticle->StartTime = timeGetTime();
  73. }
  74.  


Here is the particle struct...

  1.  
  2. struct Particle
  3. {
  4.         D3DXVECTOR2 CurrentPosition;    // The current position of the particle
  5.         D3DXVECTOR2 CurrentVelocity;    // The current velocity of the particle
  6.         DWORD Colour;                                   // The colour of the particle (RGB)
  7.         float StartTime;                                // The time the particle started
  8.         float LifeTime;                                 // The amount of time the particle has to live
  9.         int AlphaDecay;                                 // The amount of alpha which decays each second
  10.         bool Dead;                                              // The dead state of the particle
  11.         bool Mass;                                              // Affects how the particle is affected by gravity
  12. };
  13.  


Any help on this would be greatly appreciated.

Kind regards.

Mark Coleman

 
kiddygames

May 20, 2005, 02:12 AM

Hello,

can you explain us more precisely what's the problem : memory leakage, ok, but when ? when you exit the program, or do you have a crash ?

Just reading the code, I can't see anything wrong with it.

Stéphane

 
mrmcoleman

May 20, 2005, 04:11 AM

Basically... When I leave this code in, the program just continually eats up more and more memory. I can see the memory for the program steadily rising at about 50k per second. Eventually I hit the virtual memory limit and Windows whines about it...

With these three lines out, the problem does not occur!

Mark Coleman

 
Nils Pipenbrinck

May 20, 2005, 04:19 AM

You never delete the particles you've allocated.

you need something like this in your code (at the place where ParticleList goes out of scope, maybe in the destructor of your ScreenEntityParticleSystem-class).

  1.  
  2. for (ParticleList::const_iterator i = ParticleList.begin(); i != ParticleList.end(); ++i)
  3.   delete (*i);
  4.  


It would be a better idea to allocate an ordinary array of particles though.

Allocating each particle on it's own is a performance killer. New takes a lot of time, no big deal when you do it at load-time but walking a list of particles allocated one by one isn't fast either. They can be anywhere in the memory, and cpu's like to access memory in a more linear fashion.

 
_aphex_

May 20, 2005, 06:27 AM

1) What is ParticleList defined as?
2) You can allocate MaxParticles+1 in this code.
3) Probably better to put the lines:

// Increment the particle count
++CurrentParticleCount;
// Tell the particle that it is alive!
DeadParticle->Dead = false;

at the end of the InitialiseParticle method, else CurrentParticleCount will be incorrect if you exit.

 
Betelgeuse

May 20, 2005, 09:24 AM

I can't actually see anthing wrong with the code, and you aren't really doing new/delete so that's not it... if particlelist is a vector then it will free the memory when it needs to... or you can go .clear() but I don't think that will reclaim your memory (for performance reasons). You could try std::list or something, but that doesn't have O(const) access time. Dunno if that's important to you.

For this sort of thing, you really ought to use a memory manager since all your particles are of the same size. So when a particle gets nuked, another particle can take its place. std::list will not be good for this unless you supply it with your custom allocator. std::vector is ok, but everytime you push_back it will resize if there aren't many elements allocated for it... you can go vector::reserve if you kjnow you will have x number of particles... when x is reached, it will delete all the particles after new'ing 2x particles and copying x over from the old batch... bad for performance, mostly... unless you pick x very well...

Ok, so maybe use std::list with your own allocator which just gives it pointers to some contiguous block of elements. Or you could allocate new bits, but when a particle is deleted, just store the pointer but don't actually delete it, and save it for later use. This won't take care of your memory leak, but if you just recycle deleted particles your memory isn't technically leaking... You can always force delete once the number of stored "Dead" particles reaches a certain value.

Another thing, if you are using vector... you can vector.resize(vector.size()+1) and then go initialize(&vector.back()); Now, provided your vector was "reserved", so that no more memory needs to be allocated, all this does is... increment the size variable for vector, call datatype's constructor for the new element (which, if its default, compiles to no code), and then finally sends the last element's pointer to your initialize code... you can ofcourse change initialize(data* x) to initialize(data &x) to make your code safer. Anyway, this is pretty fast if since it doesn't require copying to occur.



 
Steven Hansen

May 20, 2005, 12:12 PM

And MaxParticles has what value? If uninitialized and unsigned, often the compiler will give it 0xcccccccc in debug mode. That would equate to 3,435,973,836 copies of particles that could be stored in your list. That's quite a bit of memory.

 
kiddygames

May 21, 2005, 06:05 AM

Hello,

it seems the particles are not created with new, they are just copies of structs, so a delete will not be good in this case.

Stéphane

 
[MENTAL]

May 21, 2005, 06:26 AM

1) How do you remove particles from the list?
2) What is the exact definition of MaxParticles?
3) From what I can see CurrentParticleCount is redundent as ParticleList.size () is the same thing.

 
phil

May 25, 2005, 08:27 AM

You can find other replies here. :)

 
Rui Martins

May 25, 2005, 08:44 AM

And what does ParticleList.size() returns ?
Is it the correct value ?
if it's not implemented iet, it could be returning 0 for example which will always make the condition true.

 
This thread contains 11 messages.
 
 
Hosting by Solid Eight Studios, maker of PhotoTangler Collage Maker.