Out of Memory

Discussion in 'Android Questions' started by Djembefola, Aug 10, 2011.

  1. Djembefola

    Djembefola Active Member Licensed User

    At times i get an "Out of memory"-Exception, when i restart my application.

    I can start my program and work with it, but when i finish it with the Back Button and then try to restart it, it crashes.

    The second attempt to restart it (after the Crash) is always succesful.

    The exception happens only on a tablet with 1GB RAM. On devices with smaller screens i never had this problem.

    Is there any way to catch an Out of Memory-Exception?
     
  2. Erel

    Erel Administrator Staff Member Licensed User

    Out of memory issues are usually related to bitmaps. Are you loading any large bitmaps?
     
  3. Djembefola

    Djembefola Active Member Licensed User

    Yes, with LoadBitmapSample.
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    Check the unfiltered logs and see at which step it fails.
     
  5. Djembefola

    Djembefola Active Member Licensed User

    Seems to happen, when i initialize a Canvas.


    Code:
    FATAL EXCEPTION: main
    java.lang.OutOfMemoryError
       at android.graphics.Bitmap.nativeCreate(Native Method)
       at android.graphics.Bitmap.createBitmap(
    Bitmap.java:604)
       at android.graphics.Bitmap.createBitmap(
    Bitmap.java:584)
       at anywheresoftware.b4a.objects.drawable.CanvasWrapper.Initialize(CanvasWrapper.java:
    71)
       at diva.dst.main._drawstartscreen(main.java:
    1705)
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    What device are you using (which resolution)? Can you post your code or at least the relevant parts?
     
  7. Djembefola

    Djembefola Active Member Licensed User


    The code ist pretty long and the error seems to happen in different procedures, but it is always related to the Initialization of a global canvas object. When i tested it today, the very first line of my program forced the crash (after a Restart of the Application):

    Code:
    Sub Activity_Create(FirstTime As Boolean)
    Dim w,h,g As Int

       
       cnv.Initialize(
    Activity)

    The unfiltered Log shows:

    Code:
    FATAL EXCEPTION: main
    java.lang.OutOfMemoryError
       at android.graphics.Bitmap.nativeCreate(Native Method)
       at android.graphics.Bitmap.createBitmap(
    Bitmap.java:604)
       at android.graphics.Bitmap.createBitmap(
    Bitmap.java:584)
       at anywheresoftware.b4a.objects.drawable.CanvasWrapper.Initialize(CanvasWrapper.java:
    71)
       at diva.dst.main._activity_create(main.java:
    499)
       ....
    The Device, which causes the error is an ACER Iconia A500 Tablet with 1280*800 and 1GB RAM.

    I don't have any Problems on other Devices, e.g. Samsung Galaxy II (800*480, 2GB Ram). I assume, the Iconia Tab with 1GB RAM could be a little bit underpowered for a High-Resolution Screen.
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    Are you creating more than a single canvas object?
    I see that you are initializing a canvas object in both Activity_Create and DrawStartScreen.
     
  9. Djembefola

    Djembefola Active Member Licensed User

    I have declared a Canvas Object in Sub Globals and use it in different procedures to draw bitmaps. It is initialized several times for different views.

    Code:
    Sub Globals
    Dim cnv As Canvas               'Activity Canvas
    ....
    End Sub
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    Each time that you initialize the canvas it creates a bitmap with the size of the target view. The first thing that you should make sure it that you are not creating unnecessary bitmaps, especially for the larger views or activity.
    For the activity you can create a process global bitmap and then set it as the activity background. You can draw on it with Canvas.Initialize2. This way there will be need to create a new bitmap each time the activity is created.
    You can also do it for other large views.
     
  11. Djembefola

    Djembefola Active Member Licensed User

    Ok,i will try to revise my code. Maybe, i'm using a little bit too often Wallpapers and other odds and ends.
    Thank you for your replies.
     
    Last edited: Aug 11, 2011
  12. Silentsea

    Silentsea Member Licensed User

    Hi,

    I will post in this thread, because I have a similar problem. My code works pretty good if I run trough my buttons and exit functions etc. I load images by click on a preview and then i initialize the cavas to draw. As mentioned this workes fine and I can do this a hundred times. But when I left this activity in some special ways (Back Key / Standby Click / Standby after time) next time there will be a memory problem. I can't figured it out, because if i resume out of my own functions all works fine. Some ideas? Where is the difference? It's only another resume? Is there a way to destroy old objects at resume? By the way why is a click at the back key resulting in activity pause with userclosed = true a click at standby key with userclosed = false?

    Maybe this is in relation to the cam lib from xerv which I use and which has to be loaded at resume.


    My first solution was to disable the back key in my cam modul but there is also the standby key, additionally this isn't a beautiful solution ;). Another approach was to Activity.Finish at activity_pause when pausing comes from system, but first this isn't an expected user experience and second this doesn't work either. There is also the mem leak?

    Silentsea
     
    Last edited: Aug 28, 2011
  13. agraham

    agraham Expert Licensed User

    It might be the classic "large native allocated bitmap is wrapped by a small managed bitmap wrapper and so the VM garbage collector is not collecting the wrapper because it doesn't think it's out of memory yet while the native heap is exhausted" problem. You could try explicitly freeing up the bitmaps and see if that helps.

    My PageTurnView library has a RecycleBitmap function you could use to try freeing a bitmap when you know you don't need it or it's trivial to do it with my Reflection library.
    Code:
    Dim Obj1 As Reflector
    Obj1.Target = bmp 
    ' bmp is the unwanted Bitmap
    Obj1.RunMethod("recycle")
    You can get the bitmap from a canvas but note that if the canvas is initialised on a view you will need to give that view another drawable or initialize a canvas on it before it is drawn again or you will get a "Canvas: trying to use a recycled bitmap " exception and your app will force close.
    Code:
    Obj1.Target = canv
    Obj1.Target = Obj1.GetField(
    "bw")
    Obj1.Target = Obj1.RunMethod(
    "getObject")
    Obj1.RunMethod(
    "recycle")
     
  14. Silentsea

    Silentsea Member Licensed User

    Thanks agraham,

    it works on my Acer Iconia A 500, but not on my galaxy tab. There I noticed also an other standyby process. At the Iconia (Honeycomb) it will only resume after standby, at the galaxy tab (Froyo 2.2) it will also do the create step (first = false).

    Also the mem the system wishes is about 7.600000, it doesn't matter if the canvas size is 20x20 oder 1600x1200.

    Currently I do not have any ideas, how to solve my problem.

    Silentsea
     
  15. Silentsea

    Silentsea Member Licensed User

    I've tried to isolate the problem a little bit more. If I do not call camera api (lib by xerv) there is no memory problem. Also there is no problem if I take a lower resolution of the cam. :BangHead: This results now in two questions.

    Is there a way to grab the ram of device (or how much is possible for a process)? So I can change the resolution if low memory is available.

    Why does this only happen after a new creation, it seems as the activity wouldn't be completly destroyed or something else :confused:?

    Some ideas?

    Silentsea
     
  16. Erel

    Erel Administrator Staff Member Licensed User

    Each time you call Canvas.Initialize(Activity) a new bitmap is created. Eventually the garbage collector should release the old bitmap. However as this bitmap can be very large you are getting an out of memory problem.
    The solution is to create a mutable bitmap and draw on this bitmap (using Canvas.Initialize2). This will allow you to reuse the bitmap even when the activity is destroyed.
    You can assign this bitmap as the activity background by creating a BitmapDrawable.
     
  17. Silentsea

    Silentsea Member Licensed User

    Hi Erel,

    may be there is some misunderstanding. I've tested this way:

    Code:
    cTools.Debug("before InitializeMutable")
    Dim MBitmap As Bitmap
    MBitmap.InitializeMutable(Resolution.Width,Resolution.Height)
    cvspaint.Initialize2(MBitmap)
       
    cTools.Debug(
    "before DrawBitmap")
    Dim Rect As Rect
    Rect.Initialize(0,0,Resolution.Width,Resolution.Height)
    cvspaint.DrawBitmap(picture,
    NullRect)
       
    cTools.Debug(
    "before SetBackgroundImage")
    pnlImage.SetBackgroundImage(MBitmap)
    It takes only slightly longer and the same error occurs. So my main point at the moment is, that the different os versions respond different (resume / restart), and I asked me why? Is this correct?

    Silentsea
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    You should create the bitmap only once. Use Activity_Create and check if FirstTime is true.
     
  19. Silentsea

    Silentsea Member Licensed User

    Yes I noticed and just changed that to Process_Globals, but I want some more tests before I feel happy, than I would have published my answer ;). It looks good, so thanks again Erel. :sign0142:

    Silentsea
     
  20. ondesic

    ondesic Active Member Licensed User

    Erel,

    I am having the same problem. I have 3 panels with 3 canvas. THey are each 1000x1400. I know this is a lot of memory but i find that everything runs fine the first run. THen I close it. On the Second run I get an out of memory error.

    I find if I force close the app everytime I DON'T get this problem. Is this a leak (remember it runs fine everyother time)?
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice