Finding out when and where ReferenceCountedObject's reference gets updated?

What’s the easier way to find out when and where ReferenceCountedObject gets it’s reference count changed? I’m leaking memory somehow and that would be the easiest way to find out what’s going on. But it looks like the reference count update functions of the that class are not virtual and thus probably can’t be used so that I would create my own methods for the inherited class…?

What other options do I have?

Can you just update the JUCE code directly with your test code

You mean putting the additional “virtual” keywords into JUCE code?

I am assuming you want to insert some code to help debug the problem, yes? you can modify the JUCE source directly to add whatever you need for debugging. If adding the virtual keyword is what you need, then yes. if you can insert your test code into the classes directly, then you don’t even need to override it. either way, for debugging purposes you can just consider JUCE as part of your codebase.

Why not just put a breakpoint in incRefCount() and decRefCount()?

Because there’s a lot of messages flying around per second and they all seem to trigger those methods.

Yeah that kind of debugging can be a pain. Editing the juce file seems a bit heavy handed to me though, and you might find another way around.

You could try putting a timer in your class and then have it ping the getReferenceCount() method. This wouldn’t give you a stack trace, but at least you could see when the ref count is getting called.

Also, remember the HeavyweightLeakedObjectDetector class. It should give you a stack trace of where the object was created.

If you know that a specific object is being leaked, you could put a breakpoint on its constructor (or at another point in the program where you know that the object has been created), and then use a watchpoint on the object’s refCount member. This will cause the debugger to pause whenever the refCount of that particular object is changed.

It seems that ValueTree is the main culprit that’s still holding my ReferenceCountedObjectPtr.

It seems that I need to think somehow more carefully how I use ValueTree with ReferenceCountedObjects. I used ValueTree::removeAllChildren() but it doesn’t seem to automatically delete the ref counted objects. That’s why it’s leaking. Not sure what’s the best solution to fix that. Obviously it’s an architectural issue so what’s the best practise to ensure ref counted objects get destroyed from the tree at quitting the software? Which class/instance should be responsible for what while we get to destructing class instances at quitting the software?

Are you absolutely sure? The ValueTree should automatically decrement the reference count on any held objects as soon as it is done with them.

I tried putting the following code in a blank GUI project. It prints “created” 4 times, then “destroyed” 4 times, so destruction seems to be working as intended:

    struct MyTestObject : public juce::ReferenceCountedObject
    {
        MyTestObject()              { DBG ("created"); }
        ~MyTestObject() override    { DBG ("destroyed"); }

        JUCE_LEAK_DETECTOR (MyTestObject)
    };

    juce::ValueTree tree ("tree");
    tree.setProperty ("a", new MyTestObject, nullptr);
    tree.setProperty ("b", new MyTestObject, nullptr);

    juce::ValueTree inner ("inner");
    inner.setProperty ("a", new MyTestObject, nullptr);
    inner.setProperty ("b", new MyTestObject, nullptr);

    tree.addChild (inner, -1, nullptr);

    tree.removeAllChildren (nullptr);

I think the problem is more likely to be elsewhere. Are you calling incReferenceCount anywhere in your own code (this is normally a bad idea)? Is it possible that you’re leaking the entire ValueTree somehow?

Are you storing a copy of the ValueTree inside your class? If so, it will create a cyclic dependency, and neither object will get deleted.

I figured out what it was:
The ValueTree root node was in global space so it’s destructor won’t get called when the software quits. I called the removeAllChildren() but the ref counted pointers was as a property directly at that root node. So it didn’t get removed and was still there when the leak detector did its job.

Which brings me to the question:
Is it a good idea to have a global value tree in the first place?

No, it’s not. It’d be better to keep it as a data member in your application class, or in another object whose lifetime is bounded by the lifetime of the application instance.

What about passing the tree to everywhere in the application, since all data is likely to live in that tree?

It depends. You normally wouldn’t pass the whole tree around, but instead pass individual subtrees to components that require the values in those subtrees.

So pretty much the same as regularly with any hierarchical things with classes. I’ll do that then. Thanks!