Shop OBEX P1 Docs P2 Docs Learn Events
Javelin Memory Leak Issue — Parallax Forums

Javelin Memory Leak Issue

Istha PowronIstha Powron Posts: 74
edited 2012-07-25 03:46 in General Discussion
Hello,

What a tradgedy to be posting this in a "Retired" forum.

I have modified some old code which was reading a compass and a GPS. Somehow, I have managed to modify it so that I am leaking memory badly. It only runs for about 100 cycles and then crashes with a memory out of range error.

I have checked the debugger and the memory increase is in Heap memory. It only leaks when the compass loop is active (i.e. there is data in the compass buffer)

The code is below and I can not see where I can be leaking.

Any help will be gretaly appreciated.

Regards,

Istha

import stamp.core.*;

public class Pilot_3 {

// Comms Pins
static final int COMP_IN = CPU.pin9; // Input From Compass GREEN
static final int DISP_OUT = CPU.pin12; // RS232 out to display
static final int GPS_IN = CPU.pin8; // RS232 From GPS
static final int TX_OUT = CPU.pin7; //RS232 to PC


//Booleans
// final static boolean GO = false; // Start input compare


final static char HOME = 0x01; // Position cursor upper-left
final static char CLS = '\u0010'; // Clear Screen

public static int Compass = 0;
public static int Pitch = 0;
public static int Roll = 0;
public static int Temp = 0;
static int l;



//Methods
//______________________________________________________________________________


public static void main() {

boolean COMP_VALID = false;
boolean GPS_VALID = false;
boolean NOW = false;
boolean START = false;

Uart txOut = new Uart(Uart.dirTransmit, TX_OUT, Uart.dontInvert,
Uart.speed19200,Uart.stop1);

Uart gpsIn = new Uart(Uart.dirReceive, GPS_IN, Uart.dontInvert,
Uart.speed4800,Uart.stop1);

Uart compIn = new Uart(Uart.dirReceive, COMP_IN, Uart.dontInvert,
Uart.speed19200,Uart.stop1);

Uart dispOut = new Uart(Uart.dirTransmit, DISP_OUT, Uart.dontInvert,
Uart.speed19200,Uart.stop1);

System.out.println(CLS);

StringBuffer gpsBuffer = new StringBuffer(1024);
StringBuffer InBuffer = new StringBuffer(1024);
StringBuffer OutBuffer = new StringBuffer(128);
StringBuffer CompChk = new StringBuffer(16);
StringBuffer tempBuff = new StringBuffer(128);


char c;
char k;
char j;
char a; //compass character
char g;

int mem;
int disp_count = 0;

int n;
int N;
int m;
int o;
int tail;

int pittCount =0;
int high;
int low;
int comp_start = 0;
int gps_start = 0;
int gps_end = 0; // position of dollar sign
int comp_p = 0; //Position of P for Pitch
int comp_r = 0; // Position of R for Roll
int comp_t = 0; // Position of t for temperature
int comp_end = 0; // position of asterix
int ct; //compass sentence counter
int comp_chsum = 0; // Checksum calculated
int comp_in_chsum = 0; // Checksum sent by compass

//_____________________________________________________________________________
// START - Main Program Loop
while (true)
{


//Clear string buffers
InBuffer.clear();
gpsBuffer.clear();
CompChk.clear();

c = 0xff;
k = 0xff;
j = 0xff;
pittCount =0;
comp_start = 0;
gps_start = 0; // position of dollar sign



COMP_VALID = false;
GPS_VALID = false;

n = 0;
o = 0;
m = 0;
ct = 0;

g = '\r';
comp_chsum = 33;
comp_in_chsum = 24;


//Read GPS Buffer
n = 0;
ct = 0;

while (j != '\r'&& gpsIn.byteAvailable())
{
j = (char)gpsIn.receiveByte();
gpsBuffer.append(j);

//check for NMEA start
if (j == '$')
{
gps_start = n;
ct++;
}

if (j == '*')
{
gps_end = n;
ct++;
}

n++;

}

System.out.println (gpsBuffer.toString());

c = 0xff;

//Read Compass Buffer
n = 0;
N = 0;
ct = 0;
START = false;

while (c != '\r'&& compIn.byteAvailable())
{
c = (char)compIn.receiveByte();
InBuffer.append(c);
N++;
}
// System.out.println(InBuffer.toString());
// txOut.sendString(Integer.toString(n));


for (n=0; n<N; n++)

{

c = InBuffer.charAt(n);

//check for NMEA start
if (c == '$')
{
comp_start = n;
ct=1;
START = true;
}


//check for Pitch start
else if (c == 'P' && START)
{
comp_p = n;
ct++;
}

//check for Roll start
else if (c == 'R'&& START)
{
comp_r = n;
ct++;
}

//check for Temp start
else if (c == 'T'&& START)
{
comp_t = n;
ct++;
}

//Check for NMEA end
else if (c == '*'&& START)
{
comp_end = n;
ct++;
}

}

// System.out.println ("Raw");
// System.out.println (InBuffer.toString());
// Calculate compass checksum
if(ct > 4 && (n - comp_end) > 1) //found $ and * and there's a checksum
{
// System.out.println (".");

comp_chsum = (byte)InBuffer.charAt(comp_start+1);
for (m = comp_start + 2; m < comp_end; m++)
{
comp_chsum = comp_chsum ^ (byte)InBuffer.charAt(m);
}

high = InBuffer.charAt(comp_end+1) - '0';
low = InBuffer.charAt(comp_end+2) - '0';
if (high > 9) high -= 7;
if (low > 9) low -=7;
comp_in_chsum = ((high << 4) & 0xF0) | (low & 0x0F);


// Extract heading, Pitch, Roll and Temperature
if (comp_in_chsum == comp_chsum)
{
// System.out.println (":");


COMP_VALID = true;

NOW = !NOW;

CPU.writePin(CPU.pin13,NOW);

//Read compass
tempBuff.clear();

o = comp_start + 2;

while (g != '.')
{
g = InBuffer.charAt(o);
if (g != '.') { tempBuff.append(g);}
o++;
}

Compass = Integer.parseInt(tempBuff.toString());


//Read Pitch
tempBuff.clear();
g = '\r';

o = comp_p + 1;

while (g != '.')
{
g = InBuffer.charAt(o);
if (g != '.') { tempBuff.append(g);}
o++;
}

Pitch = Integer.parseInt(tempBuff.toString());


//Read Roll
tempBuff.clear();
g = '\r';

o = comp_r + 1;

while (g != '.')
{
g = InBuffer.charAt(o);
if (g != '.') { tempBuff.append(g);}
o++;
}

Roll = Integer.parseInt(tempBuff.toString());

//Read Temp
tempBuff.clear();
g = '\r';

o = comp_t + 1;

while (g != '.')
{
g = InBuffer.charAt(o);
if (g != '.') { tempBuff.append(g);}
o++;
}

Temp = Integer.parseInt(tempBuff.toString());



// System.out.print("Comp ");
}

else
{
System.out.println ("COMPCHKSUM ERROR!");
}

}






if (COMP_VALID)// && NOW)
{

dispOut.sendString(InBuffer.toString());
System.out.println ("Comp "+Compass);
System.out.println ("Pitch "+Pitch);
System.out.println ("Roll "+Roll);
System.out.println ("Temp "+Temp);


mem = Memory.freeMemory();
System.out.println("mem"+mem);
}
else
{
// System.out.println ("COMPCHKSUM ERROR!");
}


} //END Main Program Loop
//___________________________________________________________________________
}// end main
}//end c

Comments

  • TWRackersTWRackers Posts: 33
    edited 2012-07-24 20:56
    Could you also post the previous (non-leaking) version? Looking where the changes were made will go a long way in identifying where the problem likely lies... or at least helps eliminate those areas which are probably NOT the trouble spots. Meanwhile I'll make a quick scan through your posted code to see if there's anything obvious. In general terms, the two kinds of errors that usually cause memory to be exhausted are (a) recursive function/method calls which will eat up memory from the stack end, or (b) repeated creation of objects, especially hidden ones, which use up memory from the heap end, since there's no garbage collection on the Javelin.

    (Ahh, I see you've already narrowed it down to heap memory. See next reply.)

    TWRackers
  • TWRackersTWRackers Posts: 33
    edited 2012-07-24 21:13
    DANGER DANGER DANGER

    (okay, not really)

    Look at these lines:

    System.out.println( "Comp " + Compass );
    System.out.println( "Pitch " + Pitch );
    System.out.println( "Roll " + Roll );
    System.out.println( "Temp " + Temp );

    mem = Memory.freeMemory();
    System.out.println( "mem" + mem );

    Each println parameter creates a temporary String (and I believe a StringBuffer) that you never see. So you're creating extraneous objects each time these lines execute.

    The fix is easy, and is mentioned in the Javelin manual: Replace, for example,

    System.out.println( "mem" + mem );

    with

    System.out.print( "mem" );
    System.out.println( mem );

    The key is to get rid of that string concatenation. Wouldn't be a problem if those lines weren't in a loop.

    TWRackers
  • TWRackersTWRackers Posts: 33
    edited 2012-07-24 21:19
    Meanwhile, I am sooooo glad to see someone else out there is using Javelin stamps. There aren't too many of us, are there?

    TWRackers
  • Istha PowronIstha Powron Posts: 74
    edited 2012-07-25 01:05
    Ahaaa!!!

    I was so busy making sure I had not done any string conversions I didn't see the concatonation.

    Thanks.

    Yes, it is a real tragedy. I have just ordered another 5 javelins as they are cheap and I wanted spares. They are ideal for quick fixes for simple control problems. The real power of having 4 serial ports or PWMs is fantastic. I've bitten teh bullet and bought a propellor board now that you can program in C. I hope it works.

    Istha
  • jmspaggijmspaggi Posts: 629
    edited 2012-07-25 03:46
    TWRackers wrote: »
    Meanwhile, I am sooooo glad to see someone else out there is using Javelin stamps. There aren't too many of us, are there?

    ;) I'm still using it. I have few of them managing many things in my house/car ;)

    Like Istha, I ordered few of them to be safe when they will be bo more. I bought some propellers too, I tried them, but honestly, it's way to complicated compared to the Javelin. So I will most probably look for another Java micro-c.
Sign In or Register to comment.