L
Lars
Hello all,
My program seems to suffer from some sort of memory leak problem that
I'm having trouble fixing. The background is as follows: I'm writing a
program that reads data from a socket. I then want to display the
values in a real-time diagram and write the values in a text file
along with a timestamp.
I'm experimenting in C and using XLib and I've managed to put together
a running program that reads, displays and logs data. It also handles
events (pressed keys), so that I can start and stop logging to file.
The program behaves well, except when I start logging. I use vmstat to
monitor memory usage and I see that the memory usage is constant when
I'm not logging to file, but it immediately starts to increase and
continues to do so for as long as I'm writing to file.
The program runs a loop that reads data and handles it (I've shortened
it somewhat):
int mainloop()
{
while( 1 ) {
while(!is_connected) {
printf("Not connected.\n");
establish_connection(servIP);
}
/*
* When connected, we need data within 4 seconds, otherwise we
consider
* the server to be dead. So we set the alarm(3L);
*/
alarm(3L);
/* Wait for data from the server */
if (( (bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <=
0)
&& is_connected==1 ) {
echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */
}
/*
* Since we got to this line, we have received something
* from the server.
*/
alarm(0); /* So we reset the alarm. */
echoBuffer[bytesRcvd] = '\0';
cpuValue = 100 - atoi(echoBuffer);
/*
* Check to see if logging is ON and if so, write value to file.
*/
// THIS IF-BLOCK IS THE CODE I'M MOST CONCERNED ABOUT
if(logging_on) {
seconds = time(NULL);
sprintf(fileString, "%i\t%d\n", seconds, 100 - cpuValue);
fputs(fileString, file);
fflush(file);
}
/*
* Goes through the drawing procedure;
*/
clearArea();
drawGridLines();
drawText();
plot_cpu_value();
XFlush(display); // No sure if necessary.
/*
* Checks for any Events, such as mouse clicks or button presses.
*/
if(XPending(display)) {
XNextEvent( display, &event );
switch( event.type ) {
/*
* Handle pressed keys.
*/
case KeyPress:
i = XLookupString( &event, text, 10, &key, 0 );
if ( i == 1 && text[0] == 'q' ) {
if(logging_on == 1) {
printf("Closing file");
fclose(file);
}
printf("Terminated normally.\n");
exit(0);
}
if ( i == 1 && text[0] == 'h' ) {
show_help();
}
// If I'm not already logging, I open a file
// and set logging_on = 1. If I AM already logging
// I close the open file and set logging_on = 0;
if ( i == 1 && text[0] == 's' ) {
if(logging_on == 0) {
file = fopen(file_name, "a");
if(setvbuf(file, NULL, _IONBF, 0)) {
printf("Bad setvbuf\n");
exit(1);
}
if(file == NULL) {
printf("Error: can't create file,\n");
} else {
printf("Good to go. Logging.\n");
logging_on = 1;
}
} else {
printf("Now closing file...\n");
fclose(file);
logging_on = 0;
}
}
break;
}
}
}
}
I've tried to narrow down the problem in several ways.
1) It doesn't matter if I actually read anything from the socket or if
I comment that out and explicitly set cpuValue = 5 in every loop.
2) It doesn't matter if I comment out the drawing procedures:
clearArea();
drawGridLines();
drawText();
plot_cpu_value();
XFlush(display);
3) However, it DOES matter what I write to the file. If I comment out
the part where I write the value and timestamp:
// seconds = time(NULL);
// sprintf(fileString, "%i\t%d\n", seconds, 100 - cpuValue);
// fputs(fileString, file);
and replace this with writing a constant string such as:
fputs("test", file);
It seems that the longer the string I want to write is, the faster the
memory drains away.
I've tried playing with setvbuf() without noticing any difference.
fflush() or no fflush() doesn't seem to make a difference either.
I would really appreciate any help you have to offer on how to stop
this behavour!
Thank you for your time and help,
Lars
My program seems to suffer from some sort of memory leak problem that
I'm having trouble fixing. The background is as follows: I'm writing a
program that reads data from a socket. I then want to display the
values in a real-time diagram and write the values in a text file
along with a timestamp.
I'm experimenting in C and using XLib and I've managed to put together
a running program that reads, displays and logs data. It also handles
events (pressed keys), so that I can start and stop logging to file.
The program behaves well, except when I start logging. I use vmstat to
monitor memory usage and I see that the memory usage is constant when
I'm not logging to file, but it immediately starts to increase and
continues to do so for as long as I'm writing to file.
The program runs a loop that reads data and handles it (I've shortened
it somewhat):
int mainloop()
{
while( 1 ) {
while(!is_connected) {
printf("Not connected.\n");
establish_connection(servIP);
}
/*
* When connected, we need data within 4 seconds, otherwise we
consider
* the server to be dead. So we set the alarm(3L);
*/
alarm(3L);
/* Wait for data from the server */
if (( (bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <=
0)
&& is_connected==1 ) {
echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */
}
/*
* Since we got to this line, we have received something
* from the server.
*/
alarm(0); /* So we reset the alarm. */
echoBuffer[bytesRcvd] = '\0';
cpuValue = 100 - atoi(echoBuffer);
/*
* Check to see if logging is ON and if so, write value to file.
*/
// THIS IF-BLOCK IS THE CODE I'M MOST CONCERNED ABOUT
if(logging_on) {
seconds = time(NULL);
sprintf(fileString, "%i\t%d\n", seconds, 100 - cpuValue);
fputs(fileString, file);
fflush(file);
}
/*
* Goes through the drawing procedure;
*/
clearArea();
drawGridLines();
drawText();
plot_cpu_value();
XFlush(display); // No sure if necessary.
/*
* Checks for any Events, such as mouse clicks or button presses.
*/
if(XPending(display)) {
XNextEvent( display, &event );
switch( event.type ) {
/*
* Handle pressed keys.
*/
case KeyPress:
i = XLookupString( &event, text, 10, &key, 0 );
if ( i == 1 && text[0] == 'q' ) {
if(logging_on == 1) {
printf("Closing file");
fclose(file);
}
printf("Terminated normally.\n");
exit(0);
}
if ( i == 1 && text[0] == 'h' ) {
show_help();
}
// If I'm not already logging, I open a file
// and set logging_on = 1. If I AM already logging
// I close the open file and set logging_on = 0;
if ( i == 1 && text[0] == 's' ) {
if(logging_on == 0) {
file = fopen(file_name, "a");
if(setvbuf(file, NULL, _IONBF, 0)) {
printf("Bad setvbuf\n");
exit(1);
}
if(file == NULL) {
printf("Error: can't create file,\n");
} else {
printf("Good to go. Logging.\n");
logging_on = 1;
}
} else {
printf("Now closing file...\n");
fclose(file);
logging_on = 0;
}
}
break;
}
}
}
}
I've tried to narrow down the problem in several ways.
1) It doesn't matter if I actually read anything from the socket or if
I comment that out and explicitly set cpuValue = 5 in every loop.
2) It doesn't matter if I comment out the drawing procedures:
clearArea();
drawGridLines();
drawText();
plot_cpu_value();
XFlush(display);
3) However, it DOES matter what I write to the file. If I comment out
the part where I write the value and timestamp:
// seconds = time(NULL);
// sprintf(fileString, "%i\t%d\n", seconds, 100 - cpuValue);
// fputs(fileString, file);
and replace this with writing a constant string such as:
fputs("test", file);
It seems that the longer the string I want to write is, the faster the
memory drains away.
I've tried playing with setvbuf() without noticing any difference.
fflush() or no fflush() doesn't seem to make a difference either.
I would really appreciate any help you have to offer on how to stop
this behavour!
Thank you for your time and help,
Lars