Android Question Running Out Of Memory

Wosl

Member
Guys,

I'm confused about the phenomenon that a simple operation lets the app run out of memory. Here is a snippet to show the effect:
B4X:
Sub Process_Globals
    Public DirektverbrauchWork As List
    Public NetzbezugWork As List
    Public NetzeinspeisungWork As List
End Sub
Sub Activity_Create(FirstTime As Boolean)
    Sleep(1500)        '  Start execution with a delay
    TestSum
    Log ("Done")
End Sub
Sub TestSum
    Private nRecords As Long = 500000
    Private dDirectSumTotal As Double, dSuppliedSumTotal As Double, dDeliveredSumTotal As Double
    Private dx As Double

    Log ("At start: available memory: " & HeapSize & " MBytes")
    '  Fill lists with dummy values
    DirektverbrauchWork.Initialize
    NetzbezugWork.Initialize
    NetzeinspeisungWork.Initialize
    For i = 0 To nRecords - 1
        dx = 0.1 * Rnd(-1000, 1000)
        DirektverbrauchWork.Add(dx)
        dx = 0.2 * Rnd(-2000, 2000)
        NetzbezugWork.Add(dx)
        dx = 0.3 * Rnd(-3000, 3000)
        NetzeinspeisungWork.Add(dx)
    Next
    Log ("After filling lists: available memory: " & HeapSize & " MBytes")

    '  Total sum of all data points of work data
    dDirectSumTotal    = 0.0
    dSuppliedSumTotal  = 0.0
    dDeliveredSumTotal = 0.0
    For i = 0 To nRecords - 1
        If i Mod 2000 = 0 Then
            Log ("Row "& i & " Available memory: " & HeapSize & " MBytes")
        End If
        dDirectSumTotal    = dDirectSumTotal    + DirektverbrauchWork.Get(i)
        dSuppliedSumTotal  = dSuppliedSumTotal  + NetzbezugWork.Get(i)
        dDeliveredSumTotal = dDeliveredSumTotal + NetzeinspeisungWork.Get(i)
    Next
    dDirectSumTotal    = dDirectSumTotal    / 1000.0
    dSuppliedSumTotal  = dSuppliedSumTotal  / 1000.0
    dDeliveredSumTotal = dDeliveredSumTotal / 1000.0
    Log (" ")
    Log ("Total sums of work data:")
    Log ("  DirectConsumed: " & dDirectSumTotal    & " [kWh]")
    Log ("  Supplied:       " & dSuppliedSumTotal  & " [kWh]")
    Log ("  Delivered:      " & dDeliveredSumTotal & " [kWh]")
End Sub
Sub HeapSize () As Long
    Private r As Reflector, iMem As Long
    r.Target = r.RunStaticMethod("java.lang.Runtime", "getRuntime", Null, Null)
    '  Available memory
    iMem = ((r.RunMethod("maxMemory") - r.RunMethod("totalMemory"))/(1024*1024))
    Return iMem
End Sub
The simple program fills three lists with random numbers and sums them up in a second step. The expected result of the app, which I ran under debug mode, is:
B4X:
At start: available memory: 192 MBytes
After filling lists: available memory: 192 MBytes
Row 0 Available memory: 192 MBytes
Row 2000 Available memory: 192 MBytes
Row 4000 Available memory: 192 MBytes
Row 6000 Available memory: 192 MBytes
...
Row 494000 Available memory: 192 MBytes
Row 496000 Available memory: 192 MBytes
Row 498000 Available memory: 192 MBytes
 
Total sums of work data:
  DirectConsumed: -46.17460000000026 [kWh]
  Supplied:       -10.323999999999836 [kWh]
  Delivered:      -71.28180000000437 [kWh]
Done
However, when I forgot to clean the project (under 'extras' or CTRL+P) then the result is as follows:
B4X:
At start: available memory: 192 MBytes
After filling lists: available memory: 5 MBytes
Row 0 Available memory: 5 MBytes
Row 2000 Available memory: 5 MBytes
Row 4000 Available memory: 5 MBytes
Row 6000 Available memory: 5 MBytes
Row 8000 Available memory: 5 MBytes
Row 10000 Available memory: 5 MBytes
Row 12000 Available memory: 5 MBytes
Row 14000 Available memory: 5 MBytes
Row 16000 Available memory: 2 MBytes
java.lang.OutOfMemoryError: Failed to allocate a 33554448 byte allocation with 18668848 free bytes and 17MB until OOM, target footprint 268435456, growth limit 268435456
    at java.util.HashMap.resize(HashMap.java:700)
    at java.util.HashMap.putVal(HashMap.java:659)
    at java.util.HashMap.put(HashMap.java:608)
    at anywheresoftware.b4a.shell.Shell.saveResult(Shell.java:764)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:738)
After filling the lists the memory went down to 5 MB heap stack size, the run time performance went down dramatically and the following summation ran out of memory.

It seems that this effect has something to do with the project cleaning task when the program is running in debug mode.

Can somebody explain to me the logic behind this strange behavior? What does the 'project cleaning' explicitly? How can I avoid this situation? Can I automize the project cleaning task?

Wosl
 

emexes

Expert
Licensed User
Longtime User
Your "Running Out Of Memory" headline reminded me that I have to go swap the new Android 2GB+32GB phone that I bought last night, for the 4GB+128GB one that was sitting next to it in the display cabinet. Although the specs indicate it doesn't have GLONASS, but I'll survive.

Thanks for the reminder. 🍻
 
Upvote 0
Top