Android Question Out Memory Issues

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Like so many others I have on and off memory issues.
Not do to bitmaps but to how long it seems to take java to reclaim the memory that I am no longer using. So I can go on and get some more


I came across this link: https://developer.android.com/topic/performance/memory

And was wondering could someone help me implement these routines to see if they will help
B4X:
import android.content.ComponentCallbacks2;
// Other import statements ...

public class MainActivity extends AppCompatActivity
    implements ComponentCallbacks2 {

    // Other activity code ...

    /**
     * Release memory when the UI becomes hidden or when system resources become low.
     * @param level the memory-related event that was raised.
     */
    public void onTrimMemory(int level) {

        // Determine which lifecycle or system event was raised.
        switch (level) {

            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:

                /*
                   Release any UI objects that currently hold memory.

                   The user interface has moved to the background.
                */

                break;

            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:

                /*
                   Release any memory that your app doesn't need to run.

                   The device is running low on memory while the app is running.
                   The event raised indicates the severity of the memory-related event.
                   If the event is TRIM_MEMORY_RUNNING_CRITICAL, then the system will
                   begin killing background processes.
                */

                break;

            case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:

                /*
                   Release as much memory as the process can.

                   The app is on the LRU list and the system is running low on memory.
                   The event raised indicates where the app sits within the LRU list.
                   If the event is TRIM_MEMORY_COMPLETE, the process will be one of
                   the first to be terminated.
                */

                break;

            default:
                /*
                  Release any non-critical data structures.

                  The app received an unrecognized memory level value
                  from the system. Treat this as a generic low-memory message.
                */
                break;
        }
    }
}
public void doSomethingMemoryIntensive() {

// Before doing something that requires a lot of memory,
// check to see whether the device is in a low memory state.
ActivityManager.MemoryInfo memoryInfo = getAvailableMemory();

if (!memoryInfo.lowMemory) {
// Do memory intensive work ...
}
}

B4X:
public void doSomethingMemoryIntensive() {

    // Before doing something that requires a lot of memory,
    // check to see whether the device is in a low memory state.
    ActivityManager.MemoryInfo memoryInfo = getAvailableMemory();

    if (!memoryInfo.lowMemory) {
        // Do memory intensive work ...
    }
}

// Get a MemoryInfo object for the device's current memory status.
private ActivityManager.MemoryInfo getAvailableMemory() {
    ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(memoryInfo);
    return memoryInfo;
}

And I also saw this in Stack Overflow https://stackoverflow.com/questions/3117429/garbage-collector-in-android

IS there ANYWAY we can call / force the System GC routine
B4X:
System.gc()
 

Robert Valentino

Well-Known Member
Licensed User
Longtime User
B4X:
  Max Memory =12.00 MB

 Total Free        =.31 MB

 Total Memory =12.00 MB

 Used Memory =10.69 MB

  Free Memory =.31 MB



ivePlayersID:15  Name:Doubles

~l2366256993:AlivePlayersID:16  Name:Mystery Doubles

~i:** Activity (areuse) Pause, UserClosed =rue **

~i:** Activity (main) Resume **

~l33786482:Valid Device License   6 Paying Subscriptions   4 Free Subscriptions

~i:** Activity (main) Pause, UserClosed =alse **

~i:** Activity (ainputdata) Create, isFirst =alse **

~i:** Activity (ainputdata) Resume **

~l4421037058:OpenPopupMenu

~l5375563033:  Max Memory =12.00 MB

~l6375563034:Total Free  =99.62 MB

~l7375563035:Total Memory =08.40 MB

~l8375563036: Used Memory =99.62 MB

~l9375563037: Free Memory =.78 MB

~l0325559057:001 -  Max Memory =12.00 MB

~l0325559057: Total Free        =2.38 MB

~l0325559057: Total Memory =08.40 MB

~l0325559057: Used Memory =99.62 MB

~l0325559057:  Free Memory =.78 MB

~l1325690155:Panel Height:423  Entries to show:8.134615384615385 ~l2369533728:Generating:Mystery Doubles

~l3388145923:cReplay::SetTag - Tag[      20]

~l4391750424:GeneratePairingsAll

~l5391750464:CurrentGame:0

~l6391750527:Player:Mike Leyva  Entries:1

~l7391750661:Game:0  -  Pairing (   1 ) - Mike Leyva                     to Jaynee Peel

~l8391750527:Player:Anthony Peel  Entries:1

~l9391750661:Game:0  -  Pairing (   2 ) - Anthony Peel                   to Trey Sledge

~l0391750527:Player:Mike Dingle  Entries:1

~l1391750661:Game:0  -  Pairing (   3 ) - Mike Dingle                    to Richard Weaver

~l2391750527:Player:Brennan Butts  Entries:1

~l3391750661:Game:0  -  Pairing (   4 ) - Brennan Butts                  to Ray Cardenas

~l4391750527:Player:Sterling Beadle  Entries:1 ~l5391750527:Player:Sterling Beadle  Entries:1

~l6391750661:Game:0  -  Pairing (   5 ) - Sterling Beadle                to DAnn Birkhead

~l7369533728:Generating:Doubles

~i:** Activity (ainputdata) Pause, UserClosed =alse **

~i:** Activity (aprizefund) Create, isFirst =rue **

~i:** Activity (aprizefund) Resume **

~e:aprizefund_vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv3 (java line: 993)

~e:java.lang.OutOfMemoryError: Failed to allocate a 9216012 byte allocation with 1933616 free bytes and 1888KB until OOM, max allowed footprint 536870912, growth limit 536870912

~e:       at dalvik.system.VMRuntime.newNonMovableArray(Native Method)

~e:       at android.graphics.Bitmap.nativeCreate(Native Method)

~e:       at android.graphics.Bitmap.createBitmap(Bitmap.java:977)

~e:       at android.graphics.Bitmap.createBitmap(Bitmap.java:948)

~e:       at android.graphics.Bitmap.createBitmap(Bitmap.java:915)

~e:       at anywheresoftware.b4a.objects.drawable.CanvasWrapper.Initialize(CanvasWrapper.java:81)

~e:       at com.BOBs.BOBsCommon.ct8textsize._initialize(ct8textsize.java:115)

~e:       at com.BOBs.BOBsCommon.cdropdown._initialize(cdropdown.java:2304)

~e:       at com.BOBs.BBS.aprizefund._vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv3(aprizefund.java:993)

~e:       at com.BOBs.BBS.aprizefund._activity_resume(aprizefund.java:602)

~e:       at java.lang.reflect.Method.invoke(Native Method)

~e:       at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)

~e:       at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)

~e:       at com.BOBs.BBS.aprizefund.afterFirstLayout(aprizefund.java:110)

~e:       at com.BOBs.BBS.aprizefund.access$000(aprizefund.java:17)

~e:       at com.BOBs.BBS.aprizefund$WaitForLayout.run(aprizefund.java:82)

~e:       at android.os.Handler.handleCallback(Handler.java:751)

~e:       at android.os.Handler.dispatchMessage(Handler.java:95)

~e:       at android.os.Looper.loop(Looper.java:154)

~e:       at android.app.ActivityThread.main(ActivityThread.java:6776)

~e:       at java.lang.reflect.Method.invoke(Native Method)

~e:       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)

~e:       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

java.lang.OutOfMemoryError: Failed to allocate a 9216012 byte allocation with 1933616 free bytes and 1888KB until OOM, max allowed footprint 536870912, growth limit 536870912

            at dalvik.system.VMRuntime.newNonMovableArray(Native Method)

            at android.graphics.Bitmap.nativeCreate(Native Method)

            at android.graphics.Bitmap.createBitmap(Bitmap.java:977)

            at android.graphics.Bitmap.createBitmap(Bitmap.java:948)

            at android.graphics.Bitmap.createBitmap(Bitmap.java:915)

            at anywheresoftware.b4a.objects.drawable.CanvasWrapper.Initialize(CanvasWrapper.java:81)

            at com.BOBs.BOBsCommon.ct8textsize._initialize(ct8textsize.java:115)

            at com.BOBs.BOBsCommon.cdropdown._initialize(cdropdown.java:2304)

            at com.BOBs.BBS.aprizefund._vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv3(aprizefund.java:993)

            at com.BOBs.BBS.aprizefund._activity_resume(aprizefund.java:602)

            at java.lang.reflect.Method.invoke(Native Method)

            at anywheresoftware.b4a.BA.raiseEvent2(BA.java:196)

            at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)

            at com.BOBs.BBS.aprizefund.afterFirstLayout(aprizefund.java:110)

            at com.BOBs.BBS.aprizefund.access$000(aprizefund.java:17)

            at com.BOBs.BBS.aprizefund$WaitForLayout.run(aprizefund.java:82)

            at android.os.Handler.handleCallback(Handler.java:751)

            at android.os.Handler.dispatchMessage(Handler.java:95)

            at android.os.Looper.loop(Looper.java:154)

            at android.app.ActivityThread.main(ActivityThread.java:6776)

            at java.lang.reflect.Method.invoke(Native Method)

            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)

            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

This is all I have. NOT happening on my device but on a users
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
OK, but no bitmaps but I am using a canvas to measure


B4X:
Private Sub Class_Globals
           Private MaxTextSize As Int        = 80
           Private Rate       As Float           
           Private cvs        As Canvas
           Private su            As StringUtils
End Sub


Public  Sub Initialize(Act As Activity)
           cvs.Initialize(Act)
End Sub


Public  Sub TextWidth(TargetView As Object) As Int
           Try
                 If  TargetView = Null Then
                   Log("TextWidth")
                       Return 0
                 End If
           Catch
               Log("TextWidth")
                   Return 0
           End Try
   
           Dim lbl As Label = TargetView
   
   
           Return cvs.MeasureStringWidth(lbl.Text, lbl.Typeface, lbl.TextSize)
End Sub


Private Sub CheckSize(TargetView As Object, MultipleLines As Boolean, NumLines As Int) As Boolean
           
           Try
                 If  TargetView = Null Then
                   Log("SingleLineNoLargerAndPadding")
                       Return True
                 End If
           Catch
               Log("SingleLineNoLargerAndPadding")
                   Return True
           End Try

           Dim lbl As Label = TargetView
           
           Try
               If  MultipleLines Then
                   Dim txtHeight As Int = su.MeasureMultilineTextHeight(lbl, lbl.Text)
               
                   If  NumLines > 0 Then
#if DebugX                   
                       Log("NumLines:" &NumLines &"  txtHeight:" &txtHeight &"  lbl.Height:" &lbl.Height &"  EachLine:" &(lbl.Height / NumLines) &"  TextSize:" &lbl.TextSize)
#end if
                   
                       If  txtHeight <= lbl.Height Or (lbl.Height / NumLines) >= txtHeight Then Return True
                       
                       Return False
                   Else
                       If  txtHeight > lbl.Height Then Return False
                   
                       Return True
                   End If
               Else
                   If  cvs.MeasureStringWidth(lbl.Text, lbl.Typeface, lbl.TextSize) > lbl.Width    Or _
                       su.MeasureMultilineTextHeight(lbl, lbl.Text) > lbl.Height Then
                       Return False
                   End If
               
                   Return True
               End If
           Catch
               Return False
           End Try
End Sub


Public  Sub SingleLineNoLarger(TargetView As Object)
           Try
                 If  TargetView = Null Then
                   Log("SingleLineNoLarger")
                       Return
                 End If
           Catch
               Log("SingleLineNoLager")
                   Return
           End Try
   
           Dim lbl As Label = TargetView
           
           Rate    = lbl.TextSize       
           
           Do    While Rate > 0.5
               If  CheckSize(lbl, False, 0) Then Exit
               
                 Rate         = Floor(Rate *.95)
               
               lbl.TextSize = Rate
           Loop
End Sub


Public  Sub SingleLineNoLargerAndPadding(TargetView As Object, Left As Int, Top As Int, Right As Int, Bottom As Int)
   
           Try
                 If  TargetView = Null Then
                   Log("SingleLineNoLargerAndPadding")
                       Return
                 End If
           Catch
               Log("SingleLineNoLargerAndPadding")
                   Return
           End Try

           Dim lbl        As Label        = TargetView
           Dim Java_Object As JavaObject    = lbl
       
           Java_Object.RunMethod("setPadding", Array As Object(Left, Top, Right, Bottom))         
               
           SingleLineNoLarger(lbl)
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
This is a big mistake. You are creating many huge canvases just for measurement.

Better to use a 2dip x 2dip mutable bitmap:
B4X:
Dim bmp As Bitmap
bmp.InitializeMutable(2dip, 2dip)
cvs.Initialize2(bmp)

You can also reuse the canvas instead of creating a new one each time (pass the canvas instead of the activity) however it will not matter too much once the underlying bitmap is small.
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
I had just looked at the AutoTextSizeLabel customview and changed that line to
B4X:
   Dim bmp As Bitmap
   bmp.InitializeMutable(1dip,1dip)
   cvs.Initialize2(bmp)

I know that this is ASK another question but do you think designer will ever let us change the Type without having to delete and re-add it.
Would make it so much easier to change all the fields I have on the screen to the AutoTextSizeLabel

Thanks for your help
 
Upvote 0
Top