Virtual memory rising on "repaint()" call


#1

Hi,

In my previous post I asked if it was possible to make some vertical progressbar, to make a VU Meter. Then Rock Hardbuns gave me a code to display a VU Meter. Here is this code:

[code]#ifndef METERCOMPONENT_H

class MeterComponent : public Component, public ChangeBroadcaster {
private:
GradientBrush* brsGreen;
float value;

public:

MeterComponent() : Component( T(“Slider Field Component”) ){
value = .5f;
brsGreen = new GradientBrush(Colour(0,200,0),0,0,Colour(200,200,0),0,100,false);

}

~MeterComponentComponent(){
delete brsGreen;
deleteAllChildren ();
}

void paint (Graphics& g){ 
    //background 
    g.setColour(Colour(0,0,0)); 
    g.fillRect(0,0,getWidth(),getHeight()); 


    g.setBrush(brsGreen); 
    g.fillRect(0,int(getHeight() * (1-value)),getWidth(),getHeight()); 

    //bevel outline for the entire draw area 
    g.drawBevel(0, 0, getWidth(), getHeight(), 2, Colour(100,100,100), Colours::white, 0); 
} 

float getValue(){ 
    return value; 
} 

void setValue(float v){ 
    value = jmin(jmax(v , .0f) , 1.0f);
    repaint();  // this is the line I added
} 

};[/code]

As I wanted the VU Meter to repaint itself when I set a value, I added a call to “repaint()” after setting the value in “setValue(float v)”. But I just remarked that this call to “repaint()” make the virtual memory rise a lot. In fact it doesn’t stop rising till I stop my process… Could it be linked with this call, or should I search somewhere else? Thanks in advance for your help.

I’ve created a thread to update my VU Meter. I set the value from the “run()” method. Maybe it has a link with my problem…

Leskimo


#2

Well painting does allocate off-screen bitmaps that will take up quite a bit of memory. It’s probably just that. If you’re leaking, then you’ll get warned about it when the app quits (if you’re using VC++).


#3

Hey!

I never actually tested that code. I just ripped it from another component I made which is sort of an array of sliders I used for making wavetables.

Though, I can’t see what could be wrong with it.

I guess you could try replacing the gradient with a solid colour. Or call repaint for the parent component…just to see if the behaviour is still there.

edit > doh, Jules slipped in ahead of me. :?


#4

Well I tried to call the parent component’s repaint method, or to change the gradient for a solid color, but the problem is still here… It is really annoying because it doesn’t stop rising, so at a certain point (when there is no virtual memory left…) it makes the application crash. How did you do to refresh your meters if you didn’t call the “repaint()” method?


#5

erm… no, I just meant that it would allocate a chunk of memory, not leak to the point of crashing!

Memory leaks are easy to debug:

  • quit the app
  • look at the list of leaked objects
  • figure out what they are (easy if you’ve used the juce_UseDebuggingNew macro)
  • look at where they’re allocated

#6

BTW calling repaint() from a thread is dangerous unless you use a MessageManagerLock - doesn’t it throw an assertion?


#7

Well, since it was a input component originally, it repainted after certain mouseMove calls, I.E changes to the sliders settings.


#8

nope, calling repaint() from a thread doesn’t throw me any assertion. But the problem is the same if I use for example a messageListener to update my VU Meters each time my class receive the corresponding message.
About the memory leaks: the compiler doesn’t tell me that there is any leak, it just seems to be perfectly normal…


#9

For what it’s worth, I just did a very simple test with a meter component controlled by a plain slider, and I can’t seem to get anything to happen as far as memory goes, no matter how much I yank that slider up and down.


#10

Are you sure you’re building it in debug mode? In a release build you’d get no assertions or leak info…


#11

you’re right, I was in release mode… I searched but didn’t find any explanation on how to use the juce_UseDebuggingNew macro. Could you explain me how I can figure out what the leaked objects are?


#12

Just put juce_UseDebuggingNewOperator in your classes, the same way as it’s done in every Juce class. Then the leak dump will contain info about the type of objects. That’s it.


#13

Or you can also use this.
Simply add #include <vld.h> and build in debug mode.
You’ll get a report containing both the leaked object, and the stack trace when the object was created / deleted…


#14

I’m working on a wizard, and each page of my wizard is a child of my mainComponent. I stored these pages in a std:vector<component*>. All the memory leaks I get are due to the fact that as soon as the program has finished to delete the children of the first page (deleteAllChildren()), it goes out of the destructor and sends an unhandledException here:

[code]void JUCEApplication::shutdownAppAndClearUp (bool useMaximumForce)
{
jassert (appInstance != 0);
JUCEApplication* const app = appInstance;

static bool reentrancyCheck = false;

if (! reentrancyCheck)
{
    reentrancyCheck = true;

    JUCE_TRY
    {
        // give the app a chance to clean up..
        app->shutdown();
    }

    catch (const std::exception& e)
    {
        app->unhandledException (&e, __FILE__, __LINE__);
    }
    catch (...)
    {
        app->unhandledException (0, __FILE__, __LINE__);    //<-- This is the one I get
    }


    JUCE_TRY
    {
        shutdownJuce_GUI();

        appInstance = 0;
        delete app;
    }
    JUCE_CATCH_ALL_ASSERT

    if (useMaximumForce)
    {
        Process::terminate();
    }

    reentrancyCheck = false;
}

}[/code]

Isn’t it wierd that the program calls shutdownAppAndClearUp without having deleted all the children?


#15

…so turn on your debugger’s exception-catcher so you can see what’s going on when it crashes! You’ll be deleting a dangling pointer or something.


#16

thanx for all your help you guys. I finally have a program without any memory leaks. I change my VU Meter handling, I’m finally using a timer to update them, that’s really easier.

Leskimo


#17