Android Question Memory leaks with panels?

JackKirk

Well-Known Member
Licensed User
Longtime User
Still tracking down memory issues with my app...

I believe I have isolated a problem with panels in child activities not freeing their memory when the activity is finished.

The attached zip has a minimal project which clearly illustrates the problem.

If you run the project the Main activity will present you with a simple button [Junk].

In the log there should be a line like "Used Allocated Memory = 14.3285 MB" - I'll explain this a bit later.

Tap the [Junk] button and the Junk activity will present you with a red screen with a diagonal black line.

Tap the Back button - you go back to the Main activity and the log will have a new line like "Used Allocated Memory = 22.0140 MB" - a lot more than before - memory is not being freed.

If you modify the projects Junk activity:

o in Sub Globals comment out the line Private junk_panel As Panel
o in Activity_Resume uncomment the line 'Private junk_panel As Panel

A rerun of the original steps will result in the 2 "Used Allocated Memory = ..." lines in the log being very similar - memory is being freed.

Obviously having the panel declaration in Activity_Resume is not very useful - merely did this for illustration.

The "Used Allocated Memory = ..." lines in the log are created by the Force_GC class in the project which forces a garbage collection - for more info on this see:

https://www.b4x.com/android/forum/threads/how-to-force-a-garbage-collection.68588/

Projects Main activity:
B4X:
#Region  Project Attributes
    #ApplicationLabel: Junk
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False

#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region

Sub Process_Globals
   
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private Button_Junk As Button

    Private GC As Force_GC

End Sub

Sub Activity_Create(FirstTime As Boolean)

End Sub

Sub Activity_Resume

    Activity.Color = Colors.White

    Button_Junk.Initialize("Button_Junk")
    Activity.AddView(Button_Junk, 10%x, 2%y, 80%x, 10%y)
    Button_Junk.Text = "Junk"
    Button_Junk.Typeface = Typeface.CreateNew(Typeface.MONOSPACE, Typeface.STYLE_BOLD)
    Button_Junk.TextSize = 20

    GC.Initialize
    GC.Fire

End Sub

Sub Activity_Pause(UserClosed As Boolean)

End Sub

Sub Button_Junk_Click

    StartActivity(Junk)

End Sub

Projects Junk activity:
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: False
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    'If declared here - memory not recovered at finish of activity
    Private junk_panel As Panel

End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")

End Sub

Sub Activity_Resume

    'If declared here - memory is recovered at finish of activity
    'Private junk_panel As Panel

    Private junk_canvas As Canvas

    Activity.Color = Colors.Red

    junk_panel.Initialize("")
    Activity.AddView(junk_panel, 0, 0, 100%x, 100%y)
    junk_panel.Color=Colors.Transparent

    junk_canvas.Initialize(junk_panel)

    junk_canvas.DrawLine(0, 0, 100%x, 100%y, Colors.Black, 10)

End Sub

Sub Activity_Pause (UserClosed As Boolean)

    Activity.RemoveAllViews

End Sub

Projects Force_GC class:
B4X:
Private Sub Class_Globals

    Private t As Thread
    Private r As Reflector

End Sub

Public Sub Initialize()

End Sub

Public Sub Fire

    'Set up forced OOM thread
    t.Initialise("t")

    'Start thread to force OOM
    Dim args(0) As Object
    t.Start(Me, "t_process", args)   

    'This loop keeps control here until thread dies, should take a couple millisec
    Do While t.Running

    Loop

    r.Target = r.RunStaticMethod("java.lang.Runtime", "getRuntime", Null, Null)
    Log("Used Allocated Memory = " & NumberFormat2((r.RunMethod("totalMemory") - r.RunMethod("freeMemory"))/1024/1024, 1, 4, 4, False) & " MB")
    Log(" ")

End Sub

Private Sub t_process

    'Find maximum memory process can use
    r.Target = r.RunStaticMethod("java.lang.Runtime", "getRuntime", Null, Null)
    Private maxmemory As Long = r.RunMethod("maxMemory")

    'Attempt to create an array that would fill maximum memory - will force a garbage
    'collection then bomb with OOM which will be caught by t_Ended
    Private Bomb(maxmemory / 8) As Double

End Sub

Private Sub t_Ended(Fail As Boolean, Error As String)

End Sub

Appreciate all help on this...
 

Attachments

  • Test.zip
    6.9 KB · Views: 262
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
Erel,

The attached zip uses Starter.Application_Error to catch the Force_GC.Fire OOM exception rather than the Threading library.

Not quite as elegant in my view.

Follow exact same script as in post #1 - with exactly the same result.

Regards...

PS I sent an email to you yesterday at erel@basic4ppc.com - did you get it?
 

Attachments

  • Test2.zip
    8 KB · Views: 291
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
did you get it?
No.

1. The memory usage is not related to the panels. It is related to the huge canvas that you create each time. As I wrote to you in another thread you can use a mutable bitmap instead and reuse it (Canvas.Initialize2).
2. You should never add views or create a canvas in Activity_Resume.
3. You don't need to remove the views in Activity_Pause

I've modified your project and made it continuously start the "junk" activity and close it. There were no memory errors. Make sure to test it in Release mode.
 

Attachments

  • Test.zip
    7.5 KB · Views: 285
Upvote 0
Top