Android Question [SOLVED] How to force a garbage collection

JackKirk

Well-Known Member
Licensed User
I have been frustrated with out of memory (OOM) problems in a rather large app I am developing.

After a lot of reading it seems to me that it is possible my problem might be related to inadequate or not sufficiently timely activity by the garbage collector.

About the only control over the garbage collector offered by android calls appears to be code of this nature:
B4X:
Private r As Reflector
r.RunStaticMethod("java.lang.System", "gc", Null, Null)
which merely "hints" to the OS that it might like to have a look at doing one.

I think I have found a simple, reliable and effective way of forcing a garbage collection - by precipitating a controlled OOM, the "control" coming from using the Threading library to catch the exception generated.

I have encapsulated the solution in a real simple class module (called Force_GC):
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

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


As an example:
B4X:
Sub Globals

    Private GC As Forced_GC

End Sub

Sub Activity_Resume

    'Set up forced garbage collection (this must be called otherwise get a null
    'pointer error in Fire)
    GC.Initialise

    'Fire forced garbage collection
    GC.Fire

    'Do normal Activity_Resume stuff here

End Sub
Here I have initialized and fired the class in the Main.Activity_Resume of an app in which the Main activity is merely acting as a gateway to a number of slave activities - every time a slave activity finishes the Main activity regains control and does a forced garbage collection before proceeding to its normal resumption stuff.

I'm guessing this might cause a gag reflex in some but my testing to date on a Samsung S5 running a multi hour stress test reveals no obvious problems.

There are obviously any number of other ways to use it.
 
Last edited:
Top