Hi there,
my first post here as I’m still quite new to the JUCE thing. So, my problem is that the juce leak detector marks leaked objects in the classes OSXTypeface, Typeface and MemoryBlock.
I tried including the JUCE_HEAVYWEIGHT_LEAK_DETECTOR to OSXTypeface and Typeface and it spits out this stacktrace:
*** Leaked objects detected: 1 instance(s) of class OSXTypeface
Backtrace 1
-----------------------------------------------------------------
0 Auto_Sample 0x000000010077d730 _ZN4juce11SystemStats17getStackBacktraceEv + 96
1 Auto_Sample 0x000000010097ec94 _ZN4juce31HeavyweightLeakedObjectDetectorINS_11OSXTypefaceEEC2Ev + 32
2 Auto_Sample 0x000000010097dd80 _ZN4juce31HeavyweightLeakedObjectDetectorINS_11OSXTypefaceEEC1Ev + 28
3 Auto_Sample 0x000000010097dc30 _ZN4juce11OSXTypefaceC2ERKNS_4FontE + 252
4 Auto_Sample 0x000000010090eee8 _ZN4juce11OSXTypefaceC1ERKNS_4FontE + 36
5 Auto_Sample 0x000000010090ee84 _ZN4juce8Typeface23createSystemTypefaceForERKNS_4FontE + 44
6 Auto_Sample 0x000000010090f474 _ZN4juce4Font25getDefaultTypefaceForFontERKS0_ + 572
7 Auto_Sample 0x0000000100a2d030 _ZN4juce11LookAndFeel18getTypefaceForFontERKNS_4FontE + 296
8 Auto_Sample 0x0000000100a2be3c _ZN4juceL33getTypefaceForFontFromLookAndFeelERKNS_4FontE + 48
9 Auto_Sample 0x00000001009780f8 _ZN4juce13TypefaceCache15findTypefaceForERKNS_4FontE + 832
10 Auto_Sample 0x00000001009053c8 _ZN4juce4Font18SharedFontInternal14getTypefacePtrERKS0_ + 100
11 Auto_Sample 0x00000001008a8adc _ZNK4juce4Font14getTypefacePtrEv + 48
12 Auto_Sample 0x00000001009069ec _ZNK4juce4Font19getStringWidthFloatERKNS_6StringE + 40
13 Auto_Sample 0x00000001009069b0 _ZNK4juce4Font14getStringWidthERKNS_6StringE + 32
14 Auto_Sample 0x0000000100aa2000 _ZN4juce11AlertWindow12updateLayoutEb + 104
15 Auto_Sample 0x0000000100aa1b80 _ZN4juce11AlertWindow18lookAndFeelChangedEv + 156
16 Auto_Sample 0x00000001009e4bc4 _ZN4juce9Component21sendLookAndFeelChangeEv + 60
17 Auto_Sample 0x00000001009ec8fc _ZN4juce7Desktop21setDefaultLookAndFeelEPNS_11LookAndFeelE + 204
18 Auto_Sample 0x0000000100a2cef4 _ZN4juce11LookAndFeel21setDefaultLookAndFeelEPS0_ + 40
19 Auto_Sample 0x00000001004b4bdc _ZN26SaemplAudioProcessorEditorC2ER20SaemplAudioProcessor + 240
20 Auto_Sample 0x00000001004b5058 _ZN26SaemplAudioProcessorEditorC1ER20SaemplAudioProcessor + 36
21 Auto_Sample 0x00000001004b10f8 _ZN20SaemplAudioProcessor12createEditorEv + 44
22 Auto_Sample 0x00000001006252c4 _ZN4juce14AudioProcessor20createEditorIfNeededEv + 104
23 Auto_Sample 0x000000010041ba6c _ZN4juce22StandaloneFilterWindow20MainContentComponentC2ERS0_ + 264
24 Auto_Sample 0x000000010041b934 _ZN4juce22StandaloneFilterWindow20MainContentComponentC1ERS0_ + 36
25 Auto_Sample 0x000000010040dddc _ZN4juce22StandaloneFilterWindow13updateContentEv + 44
26 Auto_Sample 0x000000010040dac8 _ZN4juce22StandaloneFilterWindowC2ERKNS_6StringENS_6ColourEPNS_11PropertySetEbS3_PKNS_18AudioDeviceManager16AudioDeviceSetupERKNS_5ArrayINS_22StandalonePluginHolder12PluginInOutsENS_20DummyCriticalSectionELi0EEEb + 468
27 Auto_Sample 0x000000010040d7e8 _ZN4juce22StandaloneFilterWindowC1ERKNS_6StringENS_6ColourEPNS_11PropertySetEbS3_PKNS_18AudioDeviceManager16AudioDeviceSetupERKNS_5ArrayINS_22StandalonePluginHolder12PluginInOutsENS_20DummyCriticalSectionELi0EEEb + 132
28 Auto_Sample 0x000000010040a7f4 _ZN4juce19StandaloneFilterApp12createWindowEv + 192
29 Auto_Sample 0x000000010040a55c _ZN4juce19StandaloneFilterApp10initialiseERKNS_6StringE + 32
30 Auto_Sample 0x00000001008670b0 _ZN4juce19JUCEApplicationBase13initialiseAppEv + 196
31 Auto_Sample 0x00000001009cc77c _ZN4juce15JUCEApplication13initialiseAppEv + 24
32 Auto_Sample 0x0000000100866e2c _ZN4juce19JUCEApplicationBase4mainEv + 300
33 Auto_Sample 0x0000000100866ca8 _ZN4juce19JUCEApplicationBase4mainEiPPKc + 68
34 Auto_Sample 0x000000010040a174 main + 56
35 dyld 0x0000000180da5058 start + 2224
It appears that the leak happens when trying to paint the “Options” button when building my plugin in Standalone mode. Because I had a custom method for
Font getTextButtonFont(TextButton&, int buttonHeight) override
I removed my custom font and reimplemented the look and feel v4 version of that method to check if that resolves the problem:
Font getTextButtonFont(TextButton&, int buttonHeight) override
{
return { jmin (16.0f, (float) buttonHeight * 0.6f) };
}
This didn’t solve my problem though and the stacktrace remains the same.
As for the MemoryBlock leak, I tried to include the heavyweight detector into the MemoryBlock class but this doesn’t work. Then I found this entry: https://forum.juce.com/t/using-juce-heavyweight-leak-detector-on-juce-classes/52930 and tried the trick that @oli1 mentioned there but this doesn’t work either because then it doesn’t want to build anymore.
The only times I’m using the MemoryBlock class in my code is in the plugin processor:
void SaemplAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
// You should use this method to store your parameters in the memory block.
// You could do that either as raw data, or use the XML or ValueTree classes
// as intermediaries to make it easy to save and load complex data.
XmlElement stateInfo("Blome_StateInfo");
XmlElement* stateInfoBody = new XmlElement("Blome_StateInfoBody");
// Store navigation panel state
String activeNavigationPanel = "";
switch (mActiveNavigationPanelType)
{
case PANELS_LIBRARY_PANEL:
activeNavigationPanel = "PANELS_LIBRARY_PANEL";
break;
case PANELS_TABLE_PANEL:
activeNavigationPanel = "PANELS_TABLE_PANEL";
break;
case PANELS_MAP_PANEL:
activeNavigationPanel = "PANELS_MAP_PANEL";
break;
default:
break;
}
stateInfoBody->setAttribute("ActiveNavigationPanel", activeNavigationPanel);
// Store sorting column title state
stateInfoBody->setAttribute("SortingColumnTitle", mSortingColumnTitle);
// Store sorting direction state
stateInfoBody->setAttribute("SortingDirection", mSortingDirection);
stateInfo.addChildElement(stateInfoBody);
copyXmlToBinary(stateInfo, destData);
}
And in these two methods:
XmlElement SampleLibraryManager::loadFileAsXml(File& inFile)
{
const InterProcessLock::ScopedLockType scopedLock(fileLock);
MemoryBlock fileData;
inFile.loadFileAsData(fileData);
XmlElement fileXml = *AudioPluginInstance::getXmlFromBinary(fileData.getData(), (int) fileData.getSize());
return fileXml;
}
void SampleLibraryManager::writeXmlToFile(XmlElement& inXml, File& inFile)
{
const InterProcessLock::ScopedLockType scopedLock(fileLock);
MemoryBlock destinationData;
AudioPluginInstance::copyXmlToBinary(inXml, destinationData);
inFile.replaceWithData(destinationData.getData(), destinationData.getSize());
}
The code to the whole project can be found here if interested or needed: GitHub
Some help would be greatly appreciated on how to solve this!
Thanks in advance