java.lang.Out OfMemoryError. Failed to allocate a 8294412 byte allocation with 7320368 free bytes

edited March 2018 in Android Mode

java.lang.Out OfMemoryError. Failed to allocate a 8294412 byte allocation with 7320368 free bytes and 6MB until OOM.

I'm only using 1 actual picture in the app. Do generated PImages take a lot of memory or something? My app runs at 1fps when it even works. Are pixel array edits feasible on mobile or is it fundamentally too slow? My app only has 5 PImages and 3 PGraphics elements. 1 of the Pimages is a .png file.

Answers

  • Are you suing the P3D renderer? Could the problem be device specific? Could it be your code? Could it be limitations of Android itself? I have seen problems of managing video stream in Android but it performs ok at lower image dimensions like 320x240. I haven't done much of image manipulation so no comments there.

    Kf

  • edited March 2018

    I'm using P3D, but it doesn't seem to make a difference which renderer I use (when it came to this test (I tried P2D and P3D). I tried running similar simple code to the TV noise script I posted earlier as a test and also ran into memory errors using only 2 Pimages.

    PImage noise;
    PImage testImages;
    
    
    PGraphics canvas;
    PGraphics canvas2;
    void setup()
    {
      size(displayWidth, displayHeight, P3D);
      frameRate(300);
      smooth(8);
      noise = createImage(100, 100, RGB);
      testImages = createImage(100, 100, RGB);
    
      noise.loadPixels();
    
      for (int y = 0; y < noise.pixels.length; )
        noise.pixels[y++] = int(random(-32, 32));
    
      noise.updatePixels();
      canvas = createGraphics(100, 100);
      canvas2 = createGraphics(100, 100);
    }
    void draw() {
      background(50);
      canvas2.beginDraw();
      image(noise, 0, 0, 100, 100);
      canvas2.endDraw();
      image(canvas2, 0, 0);
    
      fadeGraphics(canvas, 16);
      canvas.beginDraw();
    
      testImages = get(0, 0, 100, 100);
      scramble(testImages);
      canvas.image(testImages, 0, 0);
      canvas.endDraw();
      image(canvas, 0, 0, width, height);
    }
    
    void scramble(PImage pup) {
    
    
      for (int y = 0; y < testImages.pixels.length-2; ) {
        int R = pup.pixels[y+int(random(0, 2))] >> 16 & 0xFF ;
        int G = pup.pixels[y+int(random(0, 2))] >> 8 & 0xFF ;
        int B = pup.pixels[y+int(random(0, 2))] & 0xFF ; 
        pup.pixels[y++] = color(R, G, B, 40);
      }
      pup.updatePixels();
      // canvas.image(testImages, 0, 0, width, height);
    }
    
    
    void fadeGraphics(PGraphics c, int fadeAmount) {
    
      c.beginDraw();
      c.loadPixels();
    
      // iterate over pixels
      for (int i =0; i<c.pixels.length; i++) {
    
        // get alpha value
        int alpha = (c.pixels[i] >> 24) & 0xFF ;
    
        // reduce alpha value
        alpha = max(0, alpha-fadeAmount);
    
        // assign color with new alpha-value
        c.pixels[i] = alpha<<24 | (c.pixels[i]) & 0xFFFFFF ;
      }
    
      c.updatePixels();
    
    }
    

    Even this working with 100x100 pixel resolution stretched to the screen runs at low frame rates. I tested my app at 300x170px and it still runs at 1fps... Must be doing something wrong.

  • It seems like P3D might have been a big part of the problem. When I get rid of P3d the framerate is about 15 or so at 300px. Still super low but way better than before.

  •   canvas2.beginDraw();
      image(noise, 0, 0, 100, 100);
      canvas2.endDraw();
      image(canvas2, 0, 0);
    

    What is the above code suppose to do? Do you meant to write canvas2.image(noise, 0, 0, 100, 100);?

    Also notice that in your scramble() function you are not calling loadpixels.

    Also: c.pixels[i] = alpha<<24 | (c.pixels[i] & 0xFFFFFF) ; <== fix grouping

    Notice testImage's initial size is 100x100 but it gets changed to the size of your sketch in line 34.

    This does not solve your problem. It is not clear to me why you have those images and PGraphic objects and how the interact with each other. I can suggest you run your code in blocks so you can figure out what is causing the trouble. I was expecting running in P2D/P3D to improve but it seems it is happening the other way in your case.

    Kf

  • What is the above code suppose to do? Do you meant to write canvas2.image(noise, 0, 0, 100, 100);?

    Yeah, typo. This is just a a script I cobbled together to test the pixel shift function and the PGraphics structure and get() along with working with a fixed size image and then finally stretching the canvas to fill frame so the performance doesn't drop off a cliff with larger displays.

    To test those ideas the script creates an image with random noise and then displays it in the first pgraphics object, then in another pgraphics object a partial screen grab is taken of the 100x100 pixel image and then manipulated with a rgb pixel shift loop. Finally the manipulated image is displayed inside the second pgraphics envelope and then the pgraphics image is called and stretched to fill the frame. The idea was that I could do all the cpu intensive pixel edits on a small image and stretch them to the full display size without a big loss in framerate. Obviously something seems to be going wrong.

    I've employed similar code to the app I'm working on and I get 15fps at 720p with java2d renderer and 35 fps with p3d on laptop. On android I get 15fps at 170p with java2d and a wopping 1.5fps on p3d/p2d.

  • canvas2.image(noise, 0, 0, 100, 100);
    

    Resizes like this are expensive and are best avoided. I don't know whether the code is intelligent enough to know that you aren't actually resizing here (source is 100 X 100 anyway) but I'd try it without those last two parameters

  • Also, why doesn't processing delete temp files? Should they be so large? I just run a few sketches and the temp files in the userdata directory is 6gb and then I get out of space errors and need to manually delete them (200,000 files). Then I run like 15 more sketches and it's back the same way. I've also noticed it takes a long time to start processing and run sketches. I wonder if some setting is messed up or if that's normal.

  • You are working in Android mode, right? If so, yes, running your code takes longer. You can implement the logic of your code in java and then move to Android (after tweaking certain function calls). In general, temp files for android is bigger and loading simply takes more time, similar to what you will experience in AS (unless you have instant mode enable which should speed things up)

    Kf

  • edited March 2018

    Yeah, but even in Java mode it can take 30 seconds for a sketch to start sometimes. Also, when starting up processing for the first time everything locks up for 15 seconds or so and you can't click anything or change modes.

    More testing with opengl es vs default renderer.

    void setup() {
      size(displayWidth, displayHeight);
    }
    
    void draw() {
      for (int i = 0; i< 1000; i++){
      drawEllipse();}
    
      println(frameRate);
    }
    
    void drawEllipse() {
    
      ellipse(random(0,width), random(0,height), 50,50);
    }
    

    This code runs at 4-5fps on P3D and 12fps with the default shader on android. (1080p)

    On my laptop it runs at 20fps on P3D and 6fps with the default shader. (Also 1080p) Totally opposite.

    FX2D runs it blazingly fast. I'm curious why FX2D is so much faster at things like this and what are the limitations? Also, any idea what could be behind my phone being several times slower when using the opengl shaders? Is that normal behavior or is it just my phone?

Sign In or Register to comment.