Memory Management - App eating my ram

edited October 2014 in Using Processing

Hi,

I have built an application that uses image sequences, my issue is however, that the application is very memory hungry. It works pretty well on the iMac I have been developing on however when I try to run it on a mac mini (2012) which is where it will need to run, it is unusable because of lag.

Are there ways to optimize memory management or clear the cache etc so that the memory does not get clogged up?

(I have already upped the RAM in preferences to 4gb) Even on my desktop which is technically far better spec that the iMac I have serious issues with frame rates and RAM usage.

Any help is much appreciated! Will

Answers

  • you can force the garbage collector to work

    also show your code

    ;-)

  • Oh? How do I go about doing that?

    Ok ill post code, was bit reluctant to just due to sheer amount of it. :/

  • Java doesn't have a mechanism to manually release object allocated memory!
    Most we can do is get rid of ALL references and await for Java's GC do its job when it feels like to! :-<

    In order to accomplish that, pay attention which fields, arrays and other data structures are keeping track on those references. Lest object memories will linger forever and eventually you'll get outta RAM! :-SS

  • I have cut out the irrelevant parts of the application (OSC and Leap motion stuff). The remainder relating the the loading of images is below ...

      void setup() {
          size(1920, 1080, P3D);
          frameRate(30);
          lTimer = new Timer(500);
          rTimer = new Timer(500);
    
          leapMotion = new LeapMotion(this);
          oscP5 = new OscP5(this, 8000);
          loading = new Movie(this, "loading.mov");
    
          //loading.loop();
          thread("white0");
          myLAN = NetInfo.lan();
    
          myRemoteLocation = new NetAddress("192.168.1.76",9000);
        }
    
    
        //--------------------------------------------------- // LOAD MODELS // -----------------------------------------//
        //WHITE
        void white0() {
          finishedWhite0 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "WHITE0/white0-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          } 
          finishedWhite0 = true;
        }
        void white1() {
          finishedWhite1 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "WHITE1/white1-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedWhite1 = true;
        }
        void white2() {
          finishedWhite2 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "WHITE2/white2-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedWhite2 = true;
        }
        //RED
        void red0() {
          finishedRed0 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "RED0/red0-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedRed0 = true;
        }
        void red1() {
          finishedRed1 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "RED1/red1-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedRed1 = true;
        }
        void red2() {
          finishedRed2 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "RED2/red2-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedRed2 = true;
        }
    
        //YELLOW
        void yellow0() {
          finishedYellow0 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "YELLOW0/yellow0-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedYellow0 = true;
        }
        void yellow1() {
          finishedYellow1 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "YELLOW1/yellow1-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedYellow1 = true;
        }
        void yellow2() {
          finishedYellow2 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "YELLOW2/yellow2-" + nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedYellow2 = true;
        }
        // -------- Seats -----------
        void sportSeat() {
          finishedSportSeat = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "sportSeat/sportSeat"+ nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedSportSeat = true;
        }
        void stdSeat() {
          finishedStdSeat = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "stdSeat/stdSeat"+ nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedStdSeat = true;
        }
    
        //BUILDING MODELS
        //Boolean's need adding/editing
        void buildingExtDay() {
          finishedBuildingExtDay = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "Day/extDay-"+ nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedBuildingExtDay = true;
        }
        void buildingExtNight() {
          finishedBuildingExtNight = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "Night/extNight"+ nf(i, 4) + ".jpg";
            images[i] = loadImage(imageName);
          }
          finishedBuildingExtNight = true;
        }
        void buildingInt1() {
          finishedBuildingInt1 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "INT1/int1-"+ nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedBuildingInt1 = true;
        }
        void buildingInt2() {
          finishedBuildingInt2 = false;
          for (int i = 0; i < numFrames; i += 2) {
            String imageName = "INT2/int2-"+ nf(i, 4) + ".png";
            images[i] = loadImage(imageName);
          }
          finishedBuildingInt2 = true;
        }
    
        //END BUILDING MODELS
    
    
        //--------------------------------------------------- // DRAW // -----------------------------------------//
        void draw() { 
          background(0);
    
             //--------------------------------------------------- // Model Switch // -----------------------------------------//
            //MODEL SWITCH
            modelType = int(version);
            switch(modelType) {
              // -------------- WHITE0
            case 0: 
              if (white0 == false) {
                thread("white0");
                setLoadedFalse();
                white0 = true;
              }
              if (finishedWhite0 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
              // -------------- red0
            case 1: 
              if (red0 == false) {
                thread("red0");
                setLoadedFalse();
                red0 = true;
              }
              if (finishedRed0 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
    
              // -------------- yellow0
            case 2: 
              if (yellow0 == false) {
                thread("yellow0");
                setLoadedFalse();
                yellow0 = true;
              }
              if (finishedYellow0 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
    
              // -------------- white1
            case 3: 
              if (white1 == false) {
                thread("white1");
                setLoadedFalse();
                white1 = true;
              }
              if (finishedWhite1 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
              // -------------- red1
            case 4: 
              if (red1 == false) {
                thread("red1");
                setLoadedFalse();
                red1 = true;
              }
              if (finishedRed1 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
    
              // -------------- yellow1
            case 5: 
              if (yellow1 == false) {
                thread("yellow1");
                setLoadedFalse();
                yellow1 = true;
              }
              if (finishedYellow1 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
    
              // -------------- white2
            case 6: 
              if (white2 == false) {
                thread("white2");
                setLoadedFalse();
                white2 = true;
              }
              if (finishedWhite2 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
              // -------------- red2
            case 7: 
              if (red2 == false) {
                thread("red2");
                setLoadedFalse();
                red2 = true;
              }
              if (finishedRed2 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
    
              // -------------- yellow2
            case 8: 
              if (yellow2 == false) {
                thread("yellow2");
                setLoadedFalse();
                yellow2 = true;
              }
              if (finishedYellow2 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
              // -------------- stdSeat
            case 9: 
              if (stdSeat == false) {
                thread("stdSeat");
                setLoadedFalse();
                stdSeat = true;
              }
              if (finishedStdSeat == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
              // -------------- sportSeat
            case 10: 
              if (sportSeat == false) {
                thread("sportSeat");
                setLoadedFalse();
                sportSeat = true;
              }
              if (finishedSportSeat == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
    
              //Buildings
               // -------------- DAY
            case 11: 
              if (buildingExtDay == false) {
                thread("buildingExtDay");
                setLoadedFalse();
                buildingExtDay = true;
              }
              if (finishedBuildingExtDay == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
               // -------------- Night
            case 12: 
              if (buildingExtNight == false) {
                thread("buildingExtNight");
                setLoadedFalse();
                buildingExtNight = true;
              }
              if (finishedBuildingExtNight == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
               // -------------- Classic/Int2
            case 13: 
              if (buildingInt2 == false) {
                thread("buildingInt2");
                setLoadedFalse();
                buildingInt2 = true;
              }
              if (finishedBuildingInt2 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
    
               // -------------- Contemp/Int1
            case 14: 
              if (buildingInt1 == false) {
                thread("buildingInt1");
                setLoadedFalse();
                buildingInt1 = true;
              }
              if (finishedBuildingInt1 == false) {
                //Loading
                //loading.play();
                drawLoadingVid();
              } else {
                //Finished Loading
                drawModel();
              }
              break;
            }
    
    
    
          //Spin Speed & Current frame
    
          if (spinSpeed == spinBack && curFrame == 0) {
            curFrame = numFrames;
          }
          if (spinSpeed == spinFwd && curFrame == 358) {
            curFrame = 0;
          }
          if (curFrame == stopFrame) {
            spinSpeed = 0;
          }
          curFrame = curFrame + spinSpeed;
    
          //IP Address
    
          if (ipaddress == true) {
            pushMatrix();
            translate(-1000, 0);
            rotate(5*PI/4);
            fill(83, 107, 167);
            rectMode(CENTER);
            rect(0, -15, 500, 40);
            fill(255);
            textSize(36);
            textAlign(CENTER);
            println("Test");
            text("IP Address: " + myLAN, 0, 0);
            popMatrix();
    
            pushMatrix();
            translate(-100, 0);
            rotate((3*PI)/4);
            fill(83, 107, 167);
            rectMode(CENTER);
            rect(0, -15, 500, 40);
            fill(255);
            textSize(36);
            textAlign(CENTER);
            println("Test");
            text("IP Address: " + myLAN, 0, 0);
            popMatrix();
          }
          //End Draw
        }
        //--------------------------------------------------- // setLoadedFalse // -----------------------------------------//
        void setLoadedFalse() {
          white0 = false;
          white1 = false;
          white2 = false;
          red0 = false;
          red1 = false;
          red2 = false;
          yellow0 = false;
          yellow1 = false;
          yellow2 = false;
          stdSeat = false;
          sportSeat = false;
          buildingExtDay = false;
          buildingExtNight = false;
          buildingInt1 = false;
          buildingInt2 = false;
        }
        }
        //--------------------------------------------------- // drawLoadingVid // -----------------------------------------//
        void drawLoadingVid() {
          sendLockOSC();
          if (moviePlaying == false) { 
            //loading.stop();
            loading.play();
            moviePlaying = true;
          }
          translate(width/4, height/2);
    
          pushMatrix();
          imageMode(CENTER);
          rotate(3*PI/4);
          image(loading, 0, 0, 960, 316);
          popMatrix();
          //50%
          translate(width/2, 0);
    
          pushMatrix();
          imageMode(CENTER);
          rotate((5*PI)/4);
          image(loading, 0, 0, 960, 316);
          popMatrix();
        }
        //--------------------------------------------------- // drawModel // -----------------------------------------//
        void drawModel() {
          sendUnlockOSC();
          loading.stop();
          moviePlaying = false;
          translate(width/4, height/2);
    
          pushMatrix();
          imageMode(CENTER);
          rotate(3*PI/4);
          image(images[curFrame], 0, 0, vidWidth, vidHeight);
          popMatrix();
          //50%
          translate(width/2, 0);
    
          pushMatrix();
          imageMode(CENTER);
          rotate((5*PI)/4);
          image(images[curFrame], 0, 0, vidWidth, vidHeight);
          popMatrix();
        }
    
  • @GoToLoop oh dear! appears its a bit late for that for me ;)

    I have just found something in my code however that has helped greatly, I had for some stupid reason set the framerate to 50 fps. Having now set it to 30 its much smoother and less laggy, not munching through RAM quite as angrily either, seems to be leveling out about 2-3gb. (Still a lot for 1 image sequence is it not?!)

  • Function image() likes to cache PImage objects, especially when using OpenGL renderers like P2D & P3D!
    Even when you clear them when you loadImage() new 1s into images[], old 1s still linger in Processing's canvas!

    Even though that cache eventually empties, it can take some time. And if you loadImage() faster than that cache empties, you end up w/ stuffed RAM!

    Perhaps you should search this forum for image cache clear or something. It'll force memory release faster! o=>

  • I thought I had resolved the problem which I had with this but it appears not! I tried clearing the cache using g.removeCache(img); but it doesn't appear to do anything?

    It will run fine with 1 image sequence loaded but then each time I switch I have to wait 8 odd seconds to load a new one so am trying to load them all into memory so I can switch seamlessly between them or is there a way to optimise loading so that I don't have long wait times? my issue is the image sequence plays forwards and backwards through sequence depending on user input so it doesn't really allow me to load say 50 odd images ahead of where I currently am in the sequence as its unpredictable. HELP :-SS

Sign In or Register to comment.