Page 1 of 1

Memory leak image menu?

Posted: Tue Jan 21, 2020 8:16 am
by Rinzwind

Code: Select all

EnableExplicit

Global NewList IconList(), menu, e

Procedure CreateImg()
  Protected img
  img = CreateImage(#PB_Any, 24, 24, 32)
  StartDrawing(ImageOutput(img))
  Box(0, 0, 24, 24, RGB(Random(255), Random(255), Random(255)))
  StopDrawing()
  ProcedureReturn img
EndProcedure


Procedure NewMenu()
  Protected c, i, img
  If menu
    FreeMenu(menu)
  EndIf
  ClearList(IconList())
  menu = CreateImageMenu(#PB_Any, WindowID(0))
  MenuTitle("Test")
  c = 64
  For i = 0 To c
    img = CreateImg()
    AddElement(IconList())
    IconList() = img
    MenuItem(#PB_Any, "" + img, ImageID(img))
  Next
EndProcedure

Procedure RetainCounts()
  Protected img
  ForEach IconList()
    img = IconList()
    Debug "" + img + ", " + CocoaMessage(0, ImageID(img), "retainCount")
  Next    
EndProcedure


OpenWindow(0, 0, 0, 400, 300, "Test")
ButtonGadget(1, 10, 10, 120, 30, "Create Menu")
ButtonGadget(2, 10, 50, 120, 30, "Retain Count")
ButtonGadget(3, 10, 90, 120, 30, "Free Menu")

Repeat
  e = WaitWindowEvent()
  Select e
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          NewMenu()
        Case 2
          RetainCounts()
        Case 3
          ForEach IconList()
;             While CocoaMessage(0, IconList(), "retainCount")  > 1
;               CocoaMessage(0, IconList(), "release")
;             Wend
          Next
          If menu
            FreeMenu(menu)
            menu = 0
          EndIf
      EndSelect
  EndSelect
      
Until e = #PB_Event_CloseWindow


Click Create Menu
Click Retain Counts
Open/show/click menu
Click Retain Counts
Free Menu
Click Retain Counts

The images are still in memory after menu is freed? I would expect a crash because the object should not be there anymore...

Re: Memory leak image menu?

Posted: Tue Jan 21, 2020 9:13 am
by wilbert
You have to free an image created with CreateImage yourself using FreeImage.

Re: Memory leak image menu?

Posted: Tue Jan 21, 2020 9:56 am
by Fred
Yes it's your responsibility to clear the original images.

Re: Memory leak image menu?

Posted: Tue Jan 21, 2020 10:33 am
by Rinzwind
Ok, I asked because of this different example below and tried to duplicate it using normal PB images but failed to notice the freeimage stuff...

Below uses existing NSImage, uses it for menu.How to free it? retainCount still has a value after the menu is long gone.

Code: Select all

EnableExplicit

Global NewList IconList(), m, e

Procedure NewMenu()
  Protected icon, icon2, i, img, c = 64
  If m
    FreeMenu(m)
    
  EndIf
  ClearList(IconList())
  m = CreateImageMenu(#PB_Any, WindowID(0))
  MenuTitle("Test")
  ;Protected pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
  For i = 1 To c
    If icon = 0
      icon = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "iconForFileType:$", @"txt")
      AddElement(IconList())
      IconList() = icon
    EndIf
    ;Debug "A " + icon + ", " + CocoaMessage(0, icon, "retainCount")
    MenuItem(#PB_Any, "" + i + " " + icon, icon)
    ;Debug "B " + icon + ", " + CocoaMessage(0, icon, "retainCount")
  Next
EndProcedure

Procedure ReleaseCounts()
  Protected icon
  ForEach IconList()
    icon = IconList()
    Debug "" + icon + ", " + CocoaMessage(0, icon, "retainCount")
  Next    
EndProcedure

OpenWindow(0, 0, 0, 400, 300, "Test")
ButtonGadget(1, 10, 10, 60, 30, "CMenu")
ButtonGadget(2, 10, 50, 60, 30, "RCount")
ButtonGadget(3, 10, 90, 60, 30, "FMenu")

Repeat
  e = WaitWindowEvent()
  Select e
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          NewMenu()
        Case 2
          ReleaseCounts()
        Case 3
          FreeMenu(#PB_All)
          m = 0
      EndSelect
  EndSelect
      
Until e = #PB_Event_CloseWindow


Re: Memory leak image menu?

Posted: Tue Jan 21, 2020 10:50 am
by Rinzwind
Steps:

CMenu
RCount -> 64
FMenu
Wait few secs
RCount -> crash (expected)

Exit, run again
CMenu
RCount -> 64
Open the menu
RCount -> 192
FMenu
Wait few secs
RCount -> still 128

I don't know how to reliable cleanup...

Re: Memory leak image menu?

Posted: Tue Jan 21, 2020 1:45 pm
by Rinzwind
Btw also with the original PB image code it seems memory is leaked. Activity monitor shows memory increase every time one presses create menu, open the menu, free menu with this code, easily can get is passed 100 MB by just keep clicking. When one does NOT open/click the menu, NO memory increase is seen:

Code: Select all

EnableExplicit

Global NewList IconList(), menu, e

Procedure CreateImg()
  Protected img
  img = CreateImage(#PB_Any, 128, 128, 32)
  StartDrawing(ImageOutput(img))
  Box(0, 0, 128, 128, RGB(Random(255), Random(255), Random(255)))
  StopDrawing()
  ProcedureReturn img
EndProcedure


Procedure NewMenu()
  Protected c, i, img
  If menu
    FreeMenu(menu)
  EndIf
  ClearList(IconList())
  menu = CreateImageMenu(#PB_Any, WindowID(0))
  MenuTitle("Test")
  c = 128
  For i = 0 To c
    img = CreateImg()
    AddElement(IconList())
    IconList() = img
    MenuItem(#PB_Any, "" + img, ImageID(img))
  Next
EndProcedure

Procedure RetainCounts()
  Protected img
  ForEach IconList()
    img = IconList()
    Debug "" + img + ", " + CocoaMessage(0, ImageID(img), "retainCount")
  Next   
EndProcedure


OpenWindow(0, 0, 0, 400, 300, "Test")
ButtonGadget(1, 10, 10, 120, 30, "Create Menu")
ButtonGadget(2, 10, 50, 120, 30, "Retain Count")
ButtonGadget(3, 10, 90, 120, 30, "Free Menu")

Repeat
  e = WaitWindowEvent()
  Select e
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          NewMenu()
        Case 2
          RetainCounts()
        Case 3
          ForEach IconList()
;             While CocoaMessage(0, IconList(), "retainCount")  > 1
;               CocoaMessage(0, IconList(), "release")
;             Wend
          Next
          If menu
            FreeMenu(menu)
            ForEach IconList()
              FreeImage(IconList())
            Next
            menu = 0
          EndIf
      EndSelect
  EndSelect
     
Until e = #PB_Event_CloseWindow

Re: Memory leak image menu?

Posted: Tue Jan 21, 2020 2:46 pm
by Fred
Moved again for investigation

Re: Memory leak image menu?

Posted: Fri Jan 31, 2020 1:10 am
by Rinzwind
Progress? Kind of waiting for a fix. Hope it gets some attention.

Re: Memory leak image menu?

Posted: Sun Feb 02, 2020 9:44 pm
by Fred
It's a stange bug, because if we don't click on the menu, everything is fine. I we display it, the retainCount goes up to 4 which is not expected. Could be an OS X bug because usually menu are not freeed/changed at runtime.

Re: Memory leak image menu?

Posted: Mon Feb 03, 2020 3:32 am
by Rinzwind
I kind of have no other option because PB doesnt let me change menus dynamically (feature request ;))

Re: Memory leak image menu?

Posted: Mon Feb 03, 2020 9:45 am
by wilbert
It looks indeed like a macOS issue.

@Rinzwind, can't you reuse the images instead of creating new ones ?