# Grafica using A TON of memory

Hello everybody,

I’ve built a simple GUI in processing (P3) to show some sensor data in near real-time and have hit a bit of a snag with Grafica.

I’m plotting three values over a 25 point span and it quickly (20s) uses up all of my available memory and becomes very laggy.

The data is polled live and saved in a FIFO like this:

``````// located in setup we import grafica, declare our linkedLists, variables, etc.
#import grafica.*;

int nPoints = 25;

float E1, E2, E3, E4;
``````
``````void Convert2uStrain() {
//Convert to strain
//not shown....gathering data...converting data => E1, E2, E3 are floats

//Array containing the last nPoints
if (running == true) {
if (len < nPoints){
E1c.push(int(E1 * 1000000));
E3c.push(int(E3 * 1000000));
E4c.push(int(E4 * 1000000));
len++;
}
else {
E1c.removeLast();
E3c.removeLast();
E4c.removeLast();
E1c.push(int(E1 * 1000000));
E3c.push(int(E3 * 1000000));
E4c.push(int(E4 * 1000000));
}
}
}
``````

Then we’re graphing the data in another function called in draw() like this:

``````void PlotValues() {

// are we running and is the graphing mode selected?
if (running == true && graph == true) {

//setup legend
String[] legends = new String[]{"11\"", "Torsional", "27\""};
float[] leg1 = new float[]{0.07, 0.22, 0.42};
float[] leg2 = new float[]{0.92, 0.92, 0.92};

//Set up Arrays for each strain stream and initiate plot
GPointsArray points = new GPointsArray(nPoints);
GPointsArray points3 = new GPointsArray(nPoints);
GPointsArray points4 = new GPointsArray(nPoints);
GPlot plot = new GPlot(this);

//Set up plot properties
plot.setDim(450, 300);
plot.setPos(-512, 0);
plot.setXLim(0, nPoints);
plot.getXAxis().setNTicks(0);
plot.setYLim(-4000, 4000);
plot.getYAxis().setNTicks(9);
plot.getYAxis().setAxisLabelText("MicroStrain");
plot.setPointColor(color(0,200,0));

// If we are running... add the last nPoints to the graphing arrays
if (running == true && len >= nPoints) {
for (int i = 0; i < nPoints; i++) {
}

//Set which points to plot and their colors
plot.setPoints(points);
plot.setLineColor(color(0, 10, 255));
plot.getLayer("E3").setLineColor(color(255, 0, 10));
plot.getLayer("E4").setLineColor(color(0, 255, 10));

//Draw the plot its self
plot.beginDraw();
//plot.drawBox();
plot.drawXAxis();
plot.drawYAxis();
plot.drawLines();
plot.drawGridLines(GPlot.HORIZONTAL);
plot.drawLegend(legends, leg1, leg2);
plot.endDraw();
}
}
}
``````

Any tips on how I can reduce this memory hogging?

Thanks,
Twain

Are you calling plotValues in `draw()`?

Kf

Yes,

my draw() routine basically looks like:

``````void draw() {
serialEvent();  // read and parse incoming serial data

GyroShow();  //Show module twisting based on IMU

Convert2uStrain(); //convert data and save into a FIFO array

SavetoCSV(); //Save current data (E1, E3, E4) to a .csv file

PlotValues(); //Plot the values from FIFO array

}
``````

If i were to save the FIFO buffer and plot it all in a Private class function would that keep the memory local?

 Nope, that didn’t help anything. however I did move the creation of the FIFO array and the plotting into a single private function.

Thanks again for the help

The concept of having a setup and draw function is that you create in setup what persist in your application. You update your created objects in draw. I do not have much experience with Grafica but that would be my approach. I have to say probably Grafica is not the one delaying your app. I am suspecting it is your `SaveToCVS()` function. Can you show the content of that function? Remember that draw runs 60 fps (!)

Kf

2 Likes

Hi Kfajer,

I’ll look into setting up the graph just once setup(), but there’s only so much that I can move out as I need to gather the data in “real-time” before graphing it… That is, as the data comes in the graph needs to update.

I came to the assumption that it’s the graphing (not saving) that’s affecting the memory because if I comment the graphing code out the problem desists! Also the saving bit isn’t using the fifo array or anything, just saving the current variable to a .csv

For the record, SavetoCSV() looks like this:

``````//global variables
float A1, A2, A3, A4;
float E1, E2, E3, E4;
Table table;
String Path = "path/Goes/Here.csv";

//part of setup that's required
void setup() {

//Set up GIU box
size(1024, 768, P3D);
frameRate(60);
smooth();
...
table = new Table();

...
}

void SavetoCSV() {

if (A1 != 0) {
newRow.setFloat("A1", (A1));
newRow.setFloat("A2", (A2));
newRow.setFloat("A3", (A3));
newRow.setFloat("A4", (A4));

newRow.setFloat("E1", (E1*1000000));
newRow.setFloat("E3", (E3*1000000));
newRow.setFloat("E4", (E4*1000000));

saveTable(table, Path);
}
}
``````

You are creating 3 new GPointsArray and new GPlot approximately 60 times a second I doubt that garbage collection is keeping up. Is it not possible to create these in setup and reuse them each frame?

2 Likes

For those of you who are following along…

Moving the initiaion/creation of the GPlot and the GPointsArrays to setup() did indeed lighten the CPU load up and stop the memory leak!

Just need to figure out how to clear the plot each go around as it’s plotting over its self time and time again… but that should be simple.

The code currently looks like:

``````//Global variables
int nPoints = 25;
GPlot plot;

String[] legends = new String[]{"11\"", "Torsional", "27\""};
float[] leg1 = new float[]{0.07, 0.22, 0.42};
float[] leg2 = new float[]{0.92, 0.92, 0.92};

void setup() {
...
setupPlot();

...
}

void setupPlot() {
//Set up Arrays for each strain stream and initiate plot
GPointsArray points = new GPointsArray(nPoints);
GPointsArray points3 = new GPointsArray(nPoints);
GPointsArray points4 = new GPointsArray(nPoints);

for (int p = 0; p < nPoints; p++) {
}

plot = new GPlot(this);

//Set up plot properties
plot.setDim(450, 300);
plot.setPos(-512, 0);
plot.setXLim(0, nPoints);
plot.getXAxis().setNTicks(0);
plot.setYLim(-4000, 4000);
plot.getYAxis().setNTicks(9);
plot.getYAxis().setAxisLabelText("MicroStrain");
plot.setPointColor(color(0, 200, 0));

//Set which points to plot and their colors
plot.setPoints(points);

plot.setLineColor(color(0, 10, 255));
plot.getLayer("E3").setLineColor(color(255, 0, 10));
plot.getLayer("E4").setLineColor(color(0, 255, 10));

}

void PlotValues() {

//Array containing the last nPoints
if (running == true) {
if (len < nPoints) {
E1c.push(int(E1 * 1000000));
E3c.push(int(E3 * 1000000));
E4c.push(int(E4 * 1000000));
len++;
} else {
E1c.removeLast();
E3c.removeLast();
E4c.removeLast();

E1c.push(int(E1 * 1000000));
E3c.push(int(E3 * 1000000));
E4c.push(int(E4 * 1000000));
len++;
}
}

// If we are running... add the last nPoints to the graphing arrays
if (running == true && graph == true && len >= nPoints) {

//Draw the plot its self
plot.beginDraw();
//plot.drawBox();
plot.drawXAxis();
plot.drawYAxis();
plot.drawLines();
plot.drawGridLines(GPlot.HORIZONTAL);
plot.drawLegend(legends, leg1, leg2);
plot.endDraw();

for (int i = 0; i < nPoints; i++) {