Leaked objects message and callbackMessage


#1

Hi Jules

I’m coding a very basic and simple Host, and the program is ending with two jassert message while my AudioProcessorGraph destructor is called.

*** Leaked objects detected: 1 instance(s) of class class juce::CallbackMessage
*** Leaked objects detected: 1 instance(s) of class class juce::Message

The cause seems to be refCount =2 while the ReferenceCountedObjectPtr() destructor associated to the AsyncUpdaterMessage is called.

~ReferenceCountedObjectPtr()
{ if (referencedObject != 0)
referencedObject->decReferenceCount(); }

Thus, decReferenceCount() sets refCount to 1, preventing the message and the callbackMessage associated to be deleted.
I have also noted that refCount was incremented by AudioProcessorGraph::clear() called in the AudioProcessorGraph destructor, but I don’t know if this is the origin the problem.

Any recommendations of what I can change to get a cleaner end of my program.

Thanks


#2

If there are one or two CallbackMessages still queued for delivery in the system message queue when the plugin gets unloaded, then they’ll leak. Nothing much I can do about that, but it’s nothing to worry about - your DLL is getting unloaded at that point, so its heap memory will be reclaimed by the system anyway.


#3

Is there any possibilities to clear all the queues at the end of my programm, in the aim to not receive any assertion failure ?

Thanks


#4

No, it’s the OS’s internal message queue.

The only way would be for juce to maintain its own list containing all the messages that are currently waiting for delivery, and to clear them up at shutdown, which would be a waste of effort in this case, where the leak is trivial.


#5

Actually…there is a way to fix this. Implement a memory allocator that uses a static storage area:

Provide operator new and delete for CallbackMessage and its derived classes that first checks to see if space is available in the static storage area, and uses some of that first, before resorting to global operator new. On delete, check the address being deleted and see if it falls in the static storage area to know what to do.

You don’t need a full blown allocator implementation, you can simplify the algorithm by observing that callback messages and de-allocated shortly after they are created, and in almost the same order of creation. In fact this simple interface could be made to work:

[code]struct SimpleHeap
{
int bytesUsed;
int bytesRemaining;
char* nextFreeByte;
int numAllocatedBlocks;

void* alloc (int bytes)
{
void* buffer;
if (bytes <= bytesRemaining)
{
buffer = nextFreeByte;
nextFreeByte += bytes;
bytesUsed += bytes;
bytesRemaining -=bytes;
++numAllocatedBlocks;
}
else
buffer = 0;
return buffer;
}

void free (void* buffer)
{
–numAllocatedBlocks;
if (numAllocatedBlocks == 0)
{
bytesRemaining += bytesUsed;
nextFreeByte -= bytesUsed;
bytesUsed = 0;
}
}
};
[/code]

Yeah I know this might seem like a hack but it would work and it solves the problem.


#6

Well, that’s the sledgehammer-to-crack-a-nut approach!


#7

Hah yeah well, it is the only solution I can think of that 1) eliminates the leak, and 2) keeps the leak check assertions on. If you have a better way please, let me know!


#8

What about hooking DLL_CLOSE (or whatever it’s called) and taking care of it then?