Memory optimization and resizing

Hi everyone!

I’m extremely new to processing and coding as a whole, and so I have many questions. But one, in particular, I haven’t been able to find on google. I am creating a GUI dashboard that will eventually interface with an Arduino to measure and control motors and fans. I plan to use all of the libraries I have imported, through the use of text boxes, user input, graphs of sensor outputs over time, and such.

However, upon running the sketch, the task manager reports a memory usage of over 2GB, which unless I am very mistaken, is far too much for a simple program such as this. I understand that the windows task manager does not always report accurate values, but this still seems too high.

I have found that increasing the delay drastically lowers memory usage, but the application will need a fast updating UI to catch any irregular, outlying data, and so just increasing the delay is not an option for me.

I think the issue lies in my (hopefully) unoptimized resizing code, simply because I find it hard to believe I am doing it correctly. However, I could not figure out another way to allow resizing (again, a requirement for the application) in any simpler way.

Thanks for any help!

F1yin

Oh, and sorry for any fourm formatting faux pas, do let me know if I could do better.

//import libraries
import grafica.*;
import meter.*;
import controlP5.*;
import interfascia.*;

//Vars and Objects
PFont font;
//PShape rectangle; //deprecated now that current values are displayed on the meters
Meter horizontalAugerMeter, pyrolysisAugerMeter, feedstockAugerMeter;
int sensorValue; //testing sensor

int horizontalAugerRPM;
int pyrolysisAugerRPM;
int feedstockAugerRPM;
int pyrolysisChamberFanRPM; //unimpemented
int syngasBurnFanRPM; //unimpemented

//min and max input signals for the meters
int minInHorizontalAuger = 1;
int maxInHorizontalAuger = 10;
int minInPyrolysisAuger = 1;
int maxInPyrolysisAuger = 10;
int minInFeedstockAuger = 1;
int maxInFeedstockAuger = 10;

//resizing code
int minSensorValue = 100000; //need one for each sensor, the value is arbitrarily large to be out of the scope of the project. 
int maxSensorValue = -100000; //if the sensor returns values larger than this number change it to be large again.
int minHorizontalAugerRPM = 100000;
int maxHorizontalAugerRPM = -100000;
int minPyrolysisAugerRPM = 100000;
int maxPyrolysisAugerRPM = -100000;
int minFeedstockAugerRPM = 100000;
int maxFeedstockAugerRPM = -100000;

int displaysize;
boolean resized = true;

//Setup
void setup() {
    
    size(1080, 720);
    background(197,217,227);
    displaysize = width;
    surface.setResizable(true);
    
    //text settings
    font = createFont("Ebrima", 16, true);
    
    //max and min sensor values
    //create the meters; this needs to be in the resizing loop too
    horizontalAugerMeter = new Meter(this, 60, 30);
    pyrolysisAugerMeter = new Meter(this,width - (width / 4) * 2 - (width / 8), 30);
    feedstockAugerMeter = new Meter(this,width - width / 4 - 60, 30);
    
    //set the meter settings here 
    //the rest of the meter settings must be set in the loop as well to allow resize
    //horizontalAugerMeter
    horizontalAugerMeter.setMeterWidth(width / 4);
    horizontalAugerMeter.setMinInputSignal(minInHorizontalAuger);
    horizontalAugerMeter.setMaxInputSignal(maxInHorizontalAuger);
    String[] horizontalAugerscaleLabels = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10"};
    horizontalAugerMeter.setScaleLabels(horizontalAugerscaleLabels);
    horizontalAugerMeter.setTitle("Horizontal Auger RPM");
    horizontalAugerMeter.setDisplayMaximumNeedle(true);
    horizontalAugerMeter.setDisplayMinimumNeedle(true);
    //horizontalAugerMeter.setDisplayMaximumValue(true); //not needed and replaced with current value
    horizontalAugerMeter.setMaxScaleValue(10);
    
    //pyrolysisAugerMeter
    pyrolysisAugerMeter.setMeterWidth(width / 4);
    pyrolysisAugerMeter.setMinInputSignal(minInPyrolysisAuger);
    pyrolysisAugerMeter.setMaxInputSignal(maxInPyrolysisAuger);
    String[] pyrolysisAugerScaleLabels = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10"};
    pyrolysisAugerMeter.setScaleLabels(pyrolysisAugerScaleLabels);
    pyrolysisAugerMeter.setTitle("Pyrolysis Auger RPM");
    pyrolysisAugerMeter.setDisplayMaximumNeedle(true);
    pyrolysisAugerMeter.setDisplayMinimumNeedle(true);
    //pyrolysisAugerMeter.setDisplayMaximumValue(true);
    pyrolysisAugerMeter.setMaxScaleValue(10);
    
    //feedstockAugerMeter
    feedstockAugerMeter.setMeterWidth(width / 4);
    feedstockAugerMeter.setMinInputSignal(minInPyrolysisAuger);
    feedstockAugerMeter.setMaxInputSignal(maxInPyrolysisAuger);
    String[] feedstockAugerScaleLabels = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10"};
    feedstockAugerMeter.setScaleLabels(feedstockAugerScaleLabels);
    feedstockAugerMeter.setTitle("Feedstock Auger RPM");
    feedstockAugerMeter.setDisplayMaximumNeedle(true);
    feedstockAugerMeter.setDisplayMinimumNeedle(true);
    //feedstockAugerMeter.setDisplayMaximumValue(true);
    feedstockAugerMeter.setMaxScaleValue(10);
}

//Draw
void draw() {
    //--------------------
    //random sensor values 
    //--------------------
    sensorValue = (int)random(1, 11);  //random sensor value  
    horizontalAugerRPM = sensorValue;
    pyrolysisAugerRPM = sensorValue / 2 + 1;
    feedstockAugerRPM = sensorValue / 3 + 3;
    
    //--------------
    //resizing code
    //--------------
    
    //max and min value saving
    //SensorValue
    if (minSensorValue > sensorValue) {
        minSensorValue = sensorValue;
    }
    if (maxSensorValue < sensorValue) {
        maxSensorValue = sensorValue;
    }
    //horizontalAugerRPM
    if (minHorizontalAugerRPM > horizontalAugerRPM) {
        minHorizontalAugerRPM = horizontalAugerRPM;
    }
    if (maxHorizontalAugerRPM < horizontalAugerRPM) {
        maxHorizontalAugerRPM = horizontalAugerRPM;
    }
    //pyrolysisAugerRPM
    if (minPyrolysisAugerRPM > pyrolysisAugerRPM) {
        minPyrolysisAugerRPM = pyrolysisAugerRPM;
    }
    if (maxPyrolysisAugerRPM < pyrolysisAugerRPM) {
        maxPyrolysisAugerRPM = pyrolysisAugerRPM;
    }
    //feedstockAugerRPM
    if (minFeedstockAugerRPM > feedstockAugerRPM) {
        minFeedstockAugerRPM = feedstockAugerRPM;
    }
    if (maxFeedstockAugerRPM < feedstockAugerRPM) {
        maxFeedstockAugerRPM = feedstockAugerRPM;
    }
    
    //scale up all meters by replacing them
    if (width != displaysize) {
        displaysize = width; //reset displaysize
        
        //paste all meter settings again after the overwrite with added min/max values
        //Horizontal Auger
        horizontalAugerMeter = new Meter(this, 60, 30);
        horizontalAugerMeter.setMeterWidth(width / 4);
        horizontalAugerMeter.setMinInputSignal(minInHorizontalAuger);
        horizontalAugerMeter.setMaxInputSignal(maxInHorizontalAuger);
        String[] horizontalAugerscaleLabels = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10"};
        horizontalAugerMeter.setScaleLabels(horizontalAugerscaleLabels);
        horizontalAugerMeter.setTitle("Horizontal Auger RPM");
        horizontalAugerMeter.setDisplayMaximumNeedle(true);
        horizontalAugerMeter.setDisplayMinimumNeedle(true);
        //horizontalAugerMeter.setDisplayMaximumValue(true); //not needed and replaced with current value
        horizontalAugerMeter.setMaxScaleValue(10);
        horizontalAugerMeter.updateMeter(minHorizontalAugerRPM);
        horizontalAugerMeter.updateMeter(maxHorizontalAugerRPM);
        
        //Vertical Auger
        pyrolysisAugerMeter = new Meter(this,width - (width / 4) * 2 - (width / 8), 30);
        pyrolysisAugerMeter.setMeterWidth(width / 4);
        pyrolysisAugerMeter.setMinInputSignal(minInPyrolysisAuger);
        pyrolysisAugerMeter.setMaxInputSignal(maxInPyrolysisAuger);
        String[] verticalAugerScaleLabels = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10"};
        pyrolysisAugerMeter.setScaleLabels(verticalAugerScaleLabels);
        pyrolysisAugerMeter.setTitle("Pyrolysis Auger RPM");
        pyrolysisAugerMeter.setDisplayMaximumNeedle(true);
        pyrolysisAugerMeter.setDisplayMinimumNeedle(true);
        //pyrolysisAugerMeter.setDisplayMaximumValue(true);
        pyrolysisAugerMeter.setMaxScaleValue(10);
        pyrolysisAugerMeter.updateMeter(minPyrolysisAugerRPM);
        pyrolysisAugerMeter.updateMeter(maxPyrolysisAugerRPM);
        
        //feedstockAugerMeter
        feedstockAugerMeter = new Meter(this,width - width / 4 - 60, 30);
        feedstockAugerMeter.setMeterWidth(width / 4);
        feedstockAugerMeter.setMinInputSignal(minInPyrolysisAuger);
        feedstockAugerMeter.setMaxInputSignal(maxInPyrolysisAuger);
        String[] feedstockAugerScaleLabels = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10"};
        feedstockAugerMeter.setScaleLabels(feedstockAugerScaleLabels);
        feedstockAugerMeter.setTitle("Feedstock Auger RPM");
        feedstockAugerMeter.setDisplayMaximumNeedle(true);
        feedstockAugerMeter.setDisplayMinimumNeedle(true);
        //feedstockAugerMeter.setDisplayMaximumValue(true);
        feedstockAugerMeter.setMaxScaleValue(10);
        feedstockAugerMeter.updateMeter(minFeedstockAugerRPM);
        feedstockAugerMeter.updateMeter(maxFeedstockAugerRPM);
    }   
    //-----------------
    //end resizing code
    //-----------------
    
    //update the meters    
    horizontalAugerMeter.updateMeter(horizontalAugerRPM);
    pyrolysisAugerMeter.updateMeter(pyrolysisAugerRPM);
    feedstockAugerMeter.updateMeter(feedstockAugerRPM);
    
    //----------------------
    //display current values
    //----------------------
    
    //deprecated shape settings
    //rectangle = createShape(RECT, 0, 0, width / 18, width / 75);
    //rectangle.setFill(color(197,217,227));
    //rectangle.setStroke(false);
    //shape(rectangle, width / 10 + 60, width / 6.4 + 30);
    //shape(rectangle, width - (width / 4) * 2 - (width / 8) + (width / 10), width / 6.4 + 30);
    //shape(rectangle, width - (width / 4) - 60 + width / 10, width / 6.4 + 30);
    
    //font settings
    textFont(font, width / 80);
    fill(0);
    textAlign(CENTER);
    
    text(str(horizontalAugerRPM) + " RPM", width / 8 + 60, width / 6.9 + 30);
    text(str(pyrolysisAugerRPM) + " RPM", width - (width / 4) * 2, width / 6.9 + 30);
    text(str(feedstockAugerRPM) + " RPM", width - width / 8 - 60, width / 6.9 + 30);
    
    delay(200);
}

Memory usage doesn’t seem too bad at all.

Memory usage is ~300MB less for me in Processing 4 vs 3. It’s also ~200MB less with the P2D renderer. Around ~890MB in total:

image

How interesting, I guess it was indeed a problem with task manager reporting unusually high values.

Two questions though @micycle, what program are you using to view memory usage (it looks very useful), and how do you enable the P2D renderer? I only could find the article outlining the differences between it and the P3D.

JProfiler for the memory object inspection.

Select the P2D renderer by including it in size(): size(x, y, P2D);

1 Like